package com.kakarote.hrm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.*;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.*;
import cn.hutool.json.JSONUtil;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TrackHits;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.util.ObjectBuilder;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.google.common.collect.Lists;
import com.kakarote.common.field.utils.EsUtil;
import com.kakarote.common.log.entity.Content;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.core.common.Const;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.cache.CrmCacheKey;
import com.kakarote.core.common.constant.OrgConstant;
import com.kakarote.core.common.enums.DataAuthEnum;
import com.kakarote.core.common.enums.FieldEnum;
import com.kakarote.core.common.enums.SystemCodeEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.entity.EmployeeAccountInfo;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.entity.AdminMessage;
import com.kakarote.core.feign.admin.entity.AdminMessageEnum;
import com.kakarote.core.feign.admin.service.AdminFileService;
import com.kakarote.core.feign.admin.service.AdminMessageService;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.BaseUtil;
import com.kakarote.core.utils.SeparatorUtil;
import com.kakarote.core.utils.TransferUtil;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.ProbationEnum;
import com.kakarote.hrm.common.EmployeeHolder;
import com.kakarote.hrm.common.HrmCodeEnum;
import com.kakarote.hrm.common.LanguageFieldUtil;
import com.kakarote.hrm.constant.*;
import com.kakarote.hrm.cron.EmployeeChangeCron;
import com.kakarote.hrm.entity.BO.*;
import com.kakarote.hrm.entity.BO.export.*;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.hrm.entity.VO.*;
import com.kakarote.hrm.constant.HrmPostStatusEnum;
import com.kakarote.hrm.mapper.*;
import com.kakarote.hrm.service.*;
import com.kakarote.hrm.service.actionrecord.impl.CandidateActionRecordServiceImpl;
import com.kakarote.hrm.service.actionrecord.impl.EmployeeActionRecordServiceImpl;
import com.kakarote.hrm.utils.EmployeeCacheUtil;
import com.kakarote.hrm.utils.EmployeeUtil;
import com.kakarote.hrm.utils.FieldUtil;
import com.kakarote.hrm.utils.HttpUtils;
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.StringUtils;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 员工表 服务实现类
 * </p>
 *
 * @author huangmingbo
 * @since 2020-05-12
 */
@Service
public class HrmEmployeeServiceImpl extends BaseServiceImpl<HrmEmployeeMapper, HrmEmployee> implements IHrmEmployeeService {

    @Autowired
    private HrmEmployeeMapper employeeMapper;

    @Autowired
    private IHrmEmployeeDataService employeeDataService;

    @Autowired
    private IHrmEmployeeFieldService employeeFieldService;

    @Autowired
    private IHrmDeptService hrmDeptService;

    @Autowired
    private IHrmEmployeeEducationExperienceService educationExperienceService;

    @Autowired
    private IHrmEmployeeWorkExperienceService workExperienceService;

    @Autowired
    private IHrmEmployeePostService certificateService;

    @Autowired
    private IHrmEmployeeTechnicalService technicalService;

    @Autowired
    private IHrmEmployeeSpecialWorkerService specialWorkerService;

    @Autowired
    private IHrmEmployeeContactsService contactsService;

    @Autowired
    private IHrmEmployeeContactsDataService contactsDataService;

    @Autowired
    private IHrmEmployeeTrainingExperienceService trainingExperienceService;

    @Autowired
    private IHrmEmployeeChangeRecordService changeRecordService;

    @Autowired
    private IHrmInsuranceSchemeService insuranceSchemeService;

    @Autowired
    private IHrmEmployeeSocialSecurityService securityInfoService;

    @Resource
    private EmployeeActionRecordServiceImpl employeeActionRecordService;

    @Autowired
    private IHrmEmployeeQuitInfoService quitInfoService;

    @Autowired
    private IHrmRecruitChannelService recruitChannelService;

    @Autowired
    private IHrmEmployeeAbnormalChangeRecordService abnormalChangeRecordService;

    @Autowired
    private IHrmRecruitCandidateService candidateService;

    @Resource
    private CandidateActionRecordServiceImpl candidateActionRecordService;

    @Autowired
    private EmployeeUtil employeeUtil;
    @Autowired
    private AdminMessageService messageService;
    @Autowired
    private IHrmFieldExtendService hrmFieldExtendService;

    @Autowired
    private AdminFileService adminFileService;

    @Autowired
    private AdminService adminService;

    @Autowired
    private HrmEmployeeDataMapper hrmEmployeeDataMapper;

    @Autowired
    private HrmEmployeeFieldMapper hrmEmployeeFieldMapper;

    @Autowired
    private HrmDeptMapper hrmDeptMapper;

    @Autowired
    private IHrmEmployeeConcurrentPostService concurrentPostService;

    @Autowired
    private HrmEmployeeEducationExperienceMapper hrmEmployeeEducationExperienceMapper;

    @Autowired
    private HrmEmployeeContactsMapper hrmEmployeeContactsMapper;

    @Autowired
    private HrmEmployeeWorkExperienceMapper hrmEmployeeWorkExperienceMapper;

    @Autowired
    private HrmEmployeeTechnicalMapper hrmEmployeeTechnicalMapper;

    @Autowired
    private HrmEmployeeCertificateMapper hrmEmployeeCertificateMapper;

    @Autowired
    private HrmEmployeeSpecialWorkerMapper hrmEmployeeSpecialWorkerMapper;

    @Autowired
    private HrmEmployeeConcurrentPostMapper hrmEmployeeConcurrentPostMapper;

    @Autowired
    private HrmEmployeeRewardsPunishmentsService hrmEmployeeRewardsPunishmentsService;

    @Resource IHrmExamineService hrmExamineService;

    @Autowired
    private HrmEmployeeFileServiceImpl hrmEmployeeFileService;

    @Autowired
    private IHrmDataPushLogService dataPushLogService;

    @Autowired
    private HrmPushDataDetailMapper pushDataDetailMapper;

    @Autowired
    private IHrmEmployeeDataMobilizeRecordService hrmEmployeeDataMobilizeRecordService;

    @Autowired
    private IHrmEmployeeDataChangeRecordService employeeDataChangeRecordService;

    @Autowired
    private IHrmEmployeePostService employeePostService;

    @Value("${pushData.employee.get}")
    private String empGetUrl;
    @Value("${pushData.employee.add}")
    private String empAddUrl;
    @Value("${pushData.employee.update}")
    private String empUpdateUrl;
    @Value("${pushData.employee.delete}")
    private String empDeleteUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OperationLog> add(AddEmployeeBO employeeVO) {
        String jobNumber = employeeVO.getJobNumber();
        boolean exists = lambdaQuery().eq(HrmEmployee::getIsDel, 0).eq(HrmEmployee::getJobNumber, jobNumber).exists();
        if (exists) {
            throw new CrmException(HrmCodeEnum.JOB_NUMBER_EXISTED, jobNumber);
        }
        List<OperationLog> operationLogList = new ArrayList<>();
        if (employeeVO.getCandidateId() != null) {
            if (employeeVO.getEntryStatus() == 1) {
                candidateService.lambdaUpdate().set(HrmRecruitCandidate::getStatus, CandidateStatusEnum.HAVE_JOINED.getValue())
                        .set(HrmRecruitCandidate::getStatusUpdateTime, new Date())
                        .set(HrmRecruitCandidate::getEntryTime, new Date())
                        .eq(HrmRecruitCandidate::getCandidateId, employeeVO.getCandidateId()).update();
                UpdateCandidateStatusBO updateCandidateStatusBO = new UpdateCandidateStatusBO();
                updateCandidateStatusBO.setCandidateIds(Collections.singletonList(employeeVO.getCandidateId()));
                updateCandidateStatusBO.setStatus(CandidateStatusEnum.HAVE_JOINED.getValue());
                operationLogList.addAll(candidateActionRecordService.updateCandidateStatusRecord(updateCandidateStatusBO));

            } else {
                candidateService.lambdaUpdate().set(HrmRecruitCandidate::getStatus, CandidateStatusEnum.PENDING_ENTRY.getValue())
                        .set(HrmRecruitCandidate::getStatusUpdateTime, new Date())
                        .eq(HrmRecruitCandidate::getCandidateId, employeeVO.getCandidateId()).update();
                UpdateCandidateStatusBO updateCandidateStatusBO = new UpdateCandidateStatusBO();
                updateCandidateStatusBO.setCandidateIds(Collections.singletonList(employeeVO.getCandidateId()));
                updateCandidateStatusBO.setStatus(CandidateStatusEnum.PENDING_ENTRY.getValue());
                operationLogList.addAll(candidateActionRecordService.updateCandidateStatusRecord(updateCandidateStatusBO));
            }
        }
        HrmEmployee employee = BeanUtil.copyProperties(employeeVO, HrmEmployee.class);
        if (employee.getCandidateId() != null) {
            HrmRecruitCandidate candidate = candidateService.getById(employee.getCandidateId());
            employee.setChannelId(candidate.getChannelId());
        }
        transferEmployee(employee);
        employee.setCompanyAgeStartTime(employee.getEntryTime());
        employee.setEmploymentForms(1);
        this.save(employee);
        boolean mobileFieldCount = employeeFieldService.query().eq("field_name", "flied_kwbova").eq("label_group", LabelGroupEnum.COMMUNICATION.getValue()).eq("type", FieldTypeEnum.MOBILE.getValue()).exists();
        if (mobileFieldCount) {
            //若是存在自定义手机号码字段，则进行更新
            HrmEmployee hrmEmployee = employeeMapper.selectById(employee.getEmployeeId());
            JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employee.getEmployeeId());
            List<InformationFieldVO> communicationInformation = transferInformation(employeeModel, LabelGroupEnum.COMMUNICATION, fieldValueList);
            List<InformationFieldVO> informationFieldVOS = communicationInformation.stream().collect(Collectors.groupingBy(employeeData -> FiledIsFixedEnum.parse(employeeData.getIsFixed()))).get(FiledIsFixedEnum.NO_FIXED);
            String fliedKwbova = "flied_kwbova";
            List<HrmEmployeeData> hrmEmployeeInformationData = informationFieldVOS.stream()
                    .map(field -> {
                        if (fliedKwbova.equals(field.getFieldName()) && field.getType().equals(FieldTypeEnum.MOBILE.getValue())) {
                            field.setFieldValue(employee.getMobile());
                            field.setFieldValueDesc(employee.getMobile());
                        }
                        Object value = field.getFieldValue();
                        if (value == null) {
                            value = "";
                        }
                        field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                        return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                    }).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(hrmEmployeeInformationData, LabelGroupEnum.COMMUNICATION, employee.getEmployeeId());
        }
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.PERSONAL, employee.getEmployeeId());

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        operationLog.setOperationInfo(content.getDetail());

        if (employeeVO.getEntryStatus() == 1) {
            abnormalChangeRecordService.addAbnormalChangeRecord(employee.getEmployeeId(), AbnormalChangeType.NEW_ENTRY, LocalDateTime.now());
        }



        //发送通知
        AdminMessage adminMessage = new AdminMessage();
        adminMessage.setCreateUser(UserUtil.getUserId());
        adminMessage.setCreateTime(DateUtil.formatDateTime(new Date()));
        adminMessage.setRecipientUser(EmployeeCacheUtil.getUserId(employee.getEmployeeId()));
        adminMessage.setLabel(8);
        adminMessage.setType(AdminMessageEnum.HRM_EMPLOYEE_OPEN.getType());
        messageService.save(adminMessage);


        if (operationLogList.isEmpty()) {
            operationLogList.add(operationLog);
        }
        return operationLogList;
    }
    @Override
    public List<SimpleHrmEmployeeVO> queryInspectionAllEmployeeList(String employeeName) {
        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
        LambdaQueryWrapper<HrmEmployee> wrapper = new QueryWrapper<HrmEmployee>().lambda().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName, HrmEmployee::getPost,
                HrmEmployee::getEntryStatus, HrmEmployee::getIsDel, HrmEmployee::getDeptId).eq(HrmEmployee::getIsDel, 0).like(StrUtil.isNotEmpty(employeeName), HrmEmployee::getEmployeeName, employeeName);
        List<HrmEmployee> hrmEmployeeList = this.list(wrapper);
        List<SimpleHrmEmployeeVO> simpleHrmEmployeeVOList = new ArrayList<>();
        for (HrmEmployee employee : hrmEmployeeList) {
            if (employeeIds.contains(employee.getEmployeeId())) {
                simpleHrmEmployeeVOList.add(transferSimpleEmp(employee));
            }
        }
        return simpleHrmEmployeeVOList;
    }

    /**
     * 转换入职员工信息
     *
     * @return
     */
    private HrmEmployee transferEmployee(HrmEmployee employee) {
        if (employee.getIdType() != null && employee.getIdType() == IdTypeEnum.ID_CARD.getValue() && StrUtil.isNotEmpty(employee.getIdNumber())) {
            String idNumber = employee.getIdNumber();
            if (!IdcardUtil.isValidCard(idNumber)) {
                throw new CrmException(HrmCodeEnum.IDENTITY_INFORMATION_IS_ILLEGAL, idNumber);
            }
            employee.setDateOfBirth(IdcardUtil.getBirthDate(idNumber).toLocalDateTime().toLocalDate());
        }
        if (ObjectUtil.isNotNull(employee.getDateOfBirth())) {
            if (employee.getDateOfBirth().isBefore(LocalDate.now())) {
                employee.setAge(DateUtil.ageOfNow(LocalDateTimeUtil.format(employee.getDateOfBirth(), DatePattern.NORM_DATE_PATTERN)));
            }
        }
        if (employee.getEmploymentForms() != null && employee.getEmploymentForms() == EmploymentFormsEnum.OFFICIAL.getValue()) {
            if (ObjectUtil.isEmpty(employee.getProbation())) {
                employee.setProbation(0);
            }
            Integer probation = employee.getProbation();
            if (probation == 0) {
                employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                employee.setBecomeTime(employee.getEntryTime());
            } else {
                LocalDateTime dateTime = LocalDateTimeUtil.offset(employee.getEntryTime().atStartOfDay(), probation, ChronoUnit.MONTHS);
                if (dateTime.isAfter(LocalDateTimeUtil.beginOfDay(LocalDateTime.now()))) {
                    employee.setStatus(EmployeeStatusEnum.TRY_OUT.getValue());
                } else {
                    employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                }
                employee.setBecomeTime(dateTime.toLocalDate());
            }
        }
        LambdaQueryChainWrapper<HrmEmployee> wrapper = lambdaQuery().eq(HrmEmployee::getMobile, employee.getMobile()).eq(HrmEmployee::getIsDel, 0);
        boolean count;
        if (employee.getEmployeeId() == null) {
            count = wrapper.exists();
        } else {
            count = wrapper.ne(HrmEmployee::getEmployeeId, employee.getEmployeeId()).exists();
        }
        if (count) {
            throw new CrmException(HrmCodeEnum.PHONE_NUMBER_ALREADY_EXISTS, employee.getMobile());
        }
        if (StrUtil.isNotEmpty(employee.getWorkCity()) && BaseUtil.isJSON(employee.getWorkCity())) {
            JSONObject jsonObject = JSONObject.parseObject(employee.getWorkCity());
            StringBuilder workCity = new StringBuilder();
            workCity.append(jsonObject.getString("province"));
            if (StrUtil.isNotEmpty(jsonObject.getString("city"))) {
                workCity.append(jsonObject.getString("city"));
            }
            if (StrUtil.isNotEmpty(jsonObject.getString("area"))) {
                workCity.append(jsonObject.getString("area"));
            }
            employee.setWorkCity(workCity.toString());
        }
        return employee;
    }

    @Override
    public List<SimpleHrmEmployeeVO> queryAllEmployeeList(String employeeName) {
        LambdaQueryWrapper<HrmEmployee> wrapper = new QueryWrapper<HrmEmployee>().lambda().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName, HrmEmployee::getPost,
                HrmEmployee::getEntryStatus, HrmEmployee::getIsDel, HrmEmployee::getDeptId).eq(HrmEmployee::getIsDel, 0).like(StrUtil.isNotEmpty(employeeName), HrmEmployee::getEmployeeName, employeeName);
        List<HrmEmployee> hrmEmployeeList = this.list(wrapper);
        List<SimpleHrmEmployeeVO> simpleHrmEmployeeVOList = new ArrayList<>();
        for (HrmEmployee employee : hrmEmployeeList) {
            simpleHrmEmployeeVOList.add(transferSimpleEmp(employee));
        }
        return simpleHrmEmployeeVOList;
    }

    @Override
    public SimpleHrmEmployeeVO transferSimpleEmp(HrmEmployee employee) {
        SimpleHrmEmployeeVO simpleHrmEmployeeVO = new SimpleHrmEmployeeVO();
        simpleHrmEmployeeVO.setEmployeeId(employee.getEmployeeId());
        simpleHrmEmployeeVO.setEmployeeName(employee.getEmployeeName());
        int status = 1;
        if (employee.getIsDel() == 1) {
            status = 3;
        }
        if (employee.getIsDel() == 0 && employee.getEntryStatus().equals(EmployeeEntryStatusEnum.在职.getValue())) {
            status = 1;
        }
        if (employee.getIsDel() == 0 &&
                (employee.getEntryStatus().equals(EmployeeEntryStatusEnum.已离职.getValue()) ||
                        employee.getEntryStatus().equals(EmployeeEntryStatusEnum.待入职.getValue()))) {
            status = 2;
        }
        simpleHrmEmployeeVO.setStatus(status);
        simpleHrmEmployeeVO.setPost(employee.getPost());
        if (null != employee.getDeptId()) {
            DeptVO deptVO = hrmDeptService.queryById(employee.getDeptId());
            if (deptVO != null) {
                simpleHrmEmployeeVO.setDeptName(deptVO.getName());
            }
        }
        return simpleHrmEmployeeVO;
    }

    @Override
    public List<SimpleHrmEmployeeVO> queryInEmployeeList() {
        LambdaQueryWrapper<HrmEmployee> wrapper = new QueryWrapper<HrmEmployee>().lambda().select(HrmEmployee::getEmployeeId, HrmEmployee::getDeptId, HrmEmployee::getEmployeeName, HrmEmployee::getPost)
                .eq(HrmEmployee::getEntryStatus, EmployeeEntryStatusEnum.在职.getValue()).eq(HrmEmployee::getIsDel, 0);
        List<HrmEmployee> hrmEmployeeList = this.list(wrapper);
        hrmEmployeeList.forEach(employee -> {
            if (employee.getDeptId() != null) {
                DeptVO deptVO = hrmDeptService.queryById(employee.getDeptId());
                if (deptVO != null) {
                    employee.setDeptName(deptVO.getName());
                }
            }
        });
        return TransferUtil.transferList(hrmEmployeeList, SimpleHrmEmployeeVO.class);
    }

    @Override
    public PersonalInformationVO personalInformation(Long employeeId) {
        HrmEmployee hrmEmployee = employeeMapper.selectById(employeeId);
        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
        JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);

        // 更新司龄
        if (ObjectUtil.isNotNull(hrmEmployee.getCompanyAgeStartTime())) {
            long nowCompanyAge = LocalDateTimeUtil.between(hrmEmployee.getCompanyAgeStartTime().atStartOfDay(), LocalDateTime.now()).toDays() + 1;
            hrmEmployee.setCompanyAge(Convert.toInt(nowCompanyAge));
            updateById(hrmEmployee);
        }

        //基本信息
        List<InformationFieldVO> information = transferInformation(employeeModel, LabelGroupEnum.PERSONAL, fieldValueList);
        //通讯信息
        List<InformationFieldVO> communicationInformation = transferInformation(employeeModel, LabelGroupEnum.COMMUNICATION, fieldValueList);
        //教育经历
//        List<HrmEmployeeEducationExperience> educationExperienceList = educationExperienceService.lambdaQuery().eq(HrmEmployeeEducationExperience::getEmployeeId, employeeId).list().stream().sorted(Comparator.comparing(HrmEmployeeEducationExperience::getEducation,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
        List<HrmEmployeeEducationExperience> educationExperienceList = educationExperienceService.lambdaQuery().eq(HrmEmployeeEducationExperience::getEmployeeId, employeeId).list().stream().sorted(Comparator.comparing(HrmEmployeeEducationExperience::getAdmissionTime,Comparator.nullsLast(LocalDate::compareTo)).thenComparing(HrmEmployeeEducationExperience::getEducationId)).collect(Collectors.toList());
        //工作经历
        List<HrmEmployeeWorkExperience> workExperienceList = workExperienceService.lambdaQuery().eq(HrmEmployeeWorkExperience::getEmployeeId, employeeId).list().stream().sorted(Comparator.comparing(HrmEmployeeWorkExperience::getWorkStartTime,Comparator.nullsLast(LocalDate::compareTo)).thenComparing(HrmEmployeeWorkExperience::getWorkExpId)).collect(Collectors.toList());
        //证书
        List<HrmEmployeeCertificate> certificateList = certificateService.lambdaQuery().eq(HrmEmployeeCertificate::getEmployeeId, employeeId).list();
        //专业技术职务
        List<HrmEmployeeTechnical> technicalList = technicalService.lambdaQuery().eq(HrmEmployeeTechnical::getEmployeeId, employeeId).list();//专业技术职务
        List<HrmEmployeeSpecialWorker> specialWorkerList = specialWorkerService.lambdaQuery().eq(HrmEmployeeSpecialWorker::getEmployeeId, employeeId).list();
        //员工奖惩信息
        List<HrmEmployeeRewardsPunishmentsVO> punishmentsList = this.queryRewardsPunishmentsList(employeeId);
        //培训经历
        List<HrmEmployeeTrainingExperience> trainingExperienceList = trainingExperienceService.lambdaQuery().eq(HrmEmployeeTrainingExperience::getEmployeeId, employeeId).list();
        //联系人信息

        List<Map<String, Object>> hrmEmployeeContacts = new ArrayList<>();
        List<HrmEmployeeContacts> contactsList = contactsService.lambdaQuery().eq(HrmEmployeeContacts::getEmployeeId, employeeId).list();
        contactsList.forEach(contacts -> {
            QueryWrapper<HrmEmployeeContactsData> eq = Wrappers.<HrmEmployeeContactsData>query().select("field_id", "field_value", "field_value_desc").eq("contacts_id", contacts.getContactsId());
            List<HrmEmployeeContactsData> list = contactsDataService.list(eq);
            //联系人自定义字段值
            List<HrmEmployeeData> contactsFieldValueList = TransferUtil.transferList(list, HrmEmployeeData.class);
            Map<String, Object> hrmEmployeeContact = new HashMap<>();
            hrmEmployeeContact.put("contactsId", contacts.getContactsId());
            hrmEmployeeContact.put("information", transferInformation(BeanUtil.copyProperties(contacts, JSONObject.class), LabelGroupEnum.CONTACT_PERSON, contactsFieldValueList));
            hrmEmployeeContacts.add(hrmEmployeeContact);
        });

        //员工账号信息
        Result<EmployeeAccountInfo> accountInfoResult = adminService.getAccountInfoByUserName(hrmEmployee.getMobile());
        return new PersonalInformationVO(information, communicationInformation, educationExperienceList, workExperienceList, certificateList, technicalList, specialWorkerList, hrmEmployeeContacts, trainingExperienceList, punishmentsList, accountInfoResult.getData());
    }


    @Override
    public PersonalInformationVO personalArchives() {
        Long employeeId = EmployeeHolder.getEmployeeId();
        HrmEmployee hrmEmployee = employeeMapper.selectById(employeeId);
        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
        JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
        List<HrmEmployeeField> personalFieldList = employeeFieldService.lambdaQuery().eq(HrmEmployeeField::getIsHidden, 0)
                .eq(HrmEmployeeField::getLabelGroup, LabelGroupEnum.PERSONAL.getValue())
                .eq(HrmEmployeeField::getIsEmployeeVisible, 1)
                .orderByAsc(HrmEmployeeField::getSorting).list();
        //基本信息
        List<InformationFieldVO> information = transferInformation(employeeModel, personalFieldList, fieldValueList);
        List<HrmEmployeeField> communicationFieldList = employeeFieldService.lambdaQuery().eq(HrmEmployeeField::getIsHidden, 0)
                .eq(HrmEmployeeField::getLabelGroup, LabelGroupEnum.COMMUNICATION.getValue())
                .eq(HrmEmployeeField::getIsEmployeeVisible, 1)
                .orderByAsc(HrmEmployeeField::getSorting).list();
        //通讯信息
        List<InformationFieldVO> communicationInformation = transferInformation(employeeModel, communicationFieldList, fieldValueList);
        //教育经历
        List<HrmEmployeeEducationExperience> educationExperienceList = educationExperienceService.lambdaQuery().eq(HrmEmployeeEducationExperience::getEmployeeId, employeeId).list();
        //工作经历
        List<HrmEmployeeWorkExperience> workExperienceList = workExperienceService.lambdaQuery().eq(HrmEmployeeWorkExperience::getEmployeeId, employeeId).list();
        //证书
        List<HrmEmployeeCertificate> certificateList = certificateService.lambdaQuery().eq(HrmEmployeeCertificate::getEmployeeId, employeeId).list();
        //证书
        List<HrmEmployeeTechnical> technicalList = technicalService.lambdaQuery().eq(HrmEmployeeTechnical::getEmployeeId, employeeId).list();
        //证书
        List<HrmEmployeeSpecialWorker> specialWorkerList = specialWorkerService.lambdaQuery().eq(HrmEmployeeSpecialWorker::getEmployeeId, employeeId).list();
        //培训经历
        List<HrmEmployeeTrainingExperience> trainingExperienceList = trainingExperienceService.lambdaQuery().eq(HrmEmployeeTrainingExperience::getEmployeeId, employeeId).list();
        //联系人信息
        List<Map<String, Object>> hrmEmployeeContacts = new ArrayList<>();
        List<HrmEmployeeContacts> contactsList = contactsService.lambdaQuery().eq(HrmEmployeeContacts::getEmployeeId, employeeId).list();
        contactsList.forEach(contacts -> {
            QueryWrapper<HrmEmployeeContactsData> eq = Wrappers.<HrmEmployeeContactsData>query().select("field_id", "field_value", "field_value_desc").eq("contacts_id", contacts.getContactsId());
            List<HrmEmployeeContactsData> list = contactsDataService.list(eq);
            //联系人自定义字段值
            List<HrmEmployeeData> contactsFieldValueList = TransferUtil.transferList(list, HrmEmployeeData.class);
            Map<String, Object> hrmEmployeeContact = new HashMap<>();
            hrmEmployeeContact.put("contactsId", contacts.getContactsId());
            hrmEmployeeContact.put("information", transferInformation(BeanUtil.copyProperties(contacts, JSONObject.class), LabelGroupEnum.CONTACT_PERSON, contactsFieldValueList));
            hrmEmployeeContacts.add(hrmEmployeeContact);
        });
        return new PersonalInformationVO(information, communicationInformation, educationExperienceList, workExperienceList, certificateList, technicalList, specialWorkerList, hrmEmployeeContacts, trainingExperienceList, new ArrayList<>(), null);
    }

    /**
     * 自定义字段基本信息转换
     *
     * @param model
     * @param labelGroupEnum
     * @param fieldValueList
     * @return
     */
    @Override
    public List<InformationFieldVO> transferInformation(JSONObject model, LabelGroupEnum labelGroupEnum, List<HrmEmployeeData> fieldValueList) {
        List<HrmEmployeeField> hrmEmployeeFieldList = employeeFieldService.queryInformationFieldByLabelGroup(labelGroupEnum);
        return transferInformation(model, hrmEmployeeFieldList, fieldValueList);
    }

    @Override
    public List<InformationFieldVO> transferInformation(JSONObject model, List<HrmEmployeeField> hrmEmployeeFieldList, List<HrmEmployeeData> fieldValueList) {
        List<InformationFieldVO> informationFieldVOList = new ArrayList<>();
        Map<Long, HrmEmployeeData> fieldValueMap = new HashMap<>();
        fieldValueList.forEach(field -> fieldValueMap.put(field.getFieldId(), field));
        hrmEmployeeFieldList.forEach(field -> {
            InformationFieldVO fieldVO = BeanUtil.copyProperties(field, InformationFieldVO.class);
            Integer isFixed = fieldVO.getIsFixed();
            Integer type = fieldVO.getType();
            //固定字段
            if (isFixed == 1) {
                String fieldName = StrUtil.toCamelCase(fieldVO.getFieldName());
                Integer componentType = fieldVO.getComponentType();
                fieldVO.setFieldValue(model.get(fieldName) != null ? model.get(fieldName) : "");
                if (componentType == ComponentType.HRM_EMPLOYEE.getValue()) {
                    fieldVO.setFieldValueDesc(model.getLong(fieldName) != null && model.getLong(fieldName) != 0L ?
                            Optional.ofNullable(employeeMapper.selectById(model.getLong(fieldName))).map(HrmEmployee::getEmployeeName).orElse("") : "");
                } else if (componentType == ComponentType.HRM_DEPT.getValue()) {
                    fieldVO.setFieldValueDesc(model.getLong(fieldName) != null && model.getLong(fieldName) != 0L ?
                            Optional.ofNullable(hrmDeptService.getById(model.getLong(fieldName))).map(HrmDept::getName).orElse("") : "");
                } else if (componentType == ComponentType.RECRUIT_CHANNEL.getValue()) {
                    fieldVO.setFieldValueDesc(model.getLong(fieldName) != null && model.getLong(fieldName) != 0 ?
                            Optional.ofNullable(recruitChannelService.getById(model.getLong(fieldName))).map(HrmRecruitChannel::getValue).orElse("") : "");
                } else if (componentType == ComponentType.NO.getValue() && type.equals(FieldTypeEnum.SELECT.getValue())) {
                    Object value = model.get(fieldName);
                    if (value != null) {
                        List<Map<String, Object>> list = JSON.parseObject(fieldVO.getOptions(), List.class);
                        if (ObjectUtil.isNotEmpty(list)) {
                            String keyName = "value";
                            list.forEach(map -> {
                                if (map.get(keyName).equals(value)) {
                                    fieldVO.setFieldValueDesc(map.get("name"));
                                }
                            });
                        } else {
                            fieldVO.setFieldValueDesc(value);
                        }
                        fieldVO.setFieldValue(value);
                    } else {
                        fieldVO.setFieldValueDesc("");
                    }
                } else if ("companyAge".equals(fieldName)) {
                    String companyAge = EmployeeUtil.computeCompanyAge(Optional.ofNullable(model.getInteger(fieldName)).orElse(0));
                    fieldVO.setFieldValue(companyAge);
                    fieldVO.setFieldValueDesc(companyAge);
                } else {
                    if (fieldVO.getType().equals(FieldTypeEnum.DATE.getValue())) {
                        if (ObjectUtil.isNotEmpty(model.get(fieldName))) {
                            if (model.get(fieldName) instanceof LocalDateTime) {
                                fieldVO.setFieldValueDesc(LocalDateTimeUtil.format((LocalDateTime) model.get(fieldName), DatePattern.NORM_DATE_PATTERN));
                                fieldVO.setFieldValue(LocalDateTimeUtil.format((LocalDateTime) model.get(fieldName), DatePattern.NORM_DATE_PATTERN));
                            }
                            if (model.get(fieldName) instanceof LocalDate) {
                                fieldVO.setFieldValueDesc(LocalDateTimeUtil.format((LocalDate) model.get(fieldName), DatePattern.NORM_DATE_PATTERN));
                                fieldVO.setFieldValue(LocalDateTimeUtil.format((LocalDate) model.get(fieldName), DatePattern.NORM_DATE_PATTERN));
                            }
                        } else {
                            fieldVO.setFieldValueDesc("");
                            fieldVO.setFieldValue("");
                        }
                    } else {
                        fieldVO.setFieldValueDesc(model.get(fieldName) != null ? model.get(fieldName) : "");
                    }
                }
            } else {
                if (fieldValueMap.get(fieldVO.getFieldId()) != null) {
                    if (fieldVO.getType().equals(FieldEnum.AREA_POSITION.getType())) {
                        String value = fieldValueMap.get(fieldVO.getFieldId()).getFieldValue();
                        if (StrUtil.isNotEmpty(value)) {
                            String contains = "=";
                            if (value.contains(contains)) {
                                System.out.println(value);

                            } else {
                                fieldVO.setFieldValue(JSON.parseArray(value));
                                fieldVO.setFieldValueDesc(JSON.parseArray(value));
                            }
                        } else {
                            fieldVO.setFieldValue(new ArrayList<>());
                            fieldVO.setFieldValueDesc(new ArrayList<>());
                        }
                    } else if (fieldVO.getType().equals(FieldEnum.CURRENT_POSITION.getType())) {
                        fieldVO.setFieldValue(JSON.parseObject(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue()));
                        fieldVO.setFieldValueDesc(JSON.parseObject(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc()));
                    } else if (fieldVO.getType().equals(FieldEnum.FILE.getType())) {
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue())) {
                            fieldVO.setFieldValue(adminFileService.queryFileList(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue()).getData());
                        } else {
                            fieldVO.setFieldValue(new ArrayList<>());
                        }
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc())) {
                            fieldVO.setFieldValueDesc(adminFileService.queryFileList(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc()).getData());
                        } else {
                            fieldVO.setFieldValueDesc(new ArrayList<>());
                        }
                    } else if (fieldVO.getType().equals(FieldEnum.STRUCTURE.getType())) {
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue())) {
                            fieldVO.setFieldValue(hrmDeptService.querySimpleDeptList(SeparatorUtil.toLongSet(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue())));
                        } else {
                            fieldVO.setFieldValue(new ArrayList<>());
                        }
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc())) {
                            fieldVO.setFieldValueDesc(hrmDeptService.querySimpleDeptList(SeparatorUtil.toLongSet(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc())));
                        } else {
                            fieldVO.setFieldValueDesc(new ArrayList<>());
                        }
                    } else if (fieldVO.getType().equals(FieldEnum.USER.getType())) {
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue())) {
                            fieldVO.setFieldValue(querySimpleEmployeeList(SeparatorUtil.toLongSet(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue())));
                        } else {
                            fieldVO.setFieldValue(new ArrayList<>());
                        }
                        if (StrUtil.isNotEmpty(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc())) {
                            fieldVO.setFieldValueDesc(querySimpleEmployeeList(SeparatorUtil.toLongSet(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc())));
                        } else {
                            fieldVO.setFieldValueDesc(new ArrayList<>());
                        }
                    } else {
                        fieldVO.setFieldValue(fieldValueMap.get(fieldVO.getFieldId()).getFieldValue());
                        fieldVO.setFieldValueDesc(fieldValueMap.get(fieldVO.getFieldId()).getFieldValueDesc());
                    }
                } else {
                    fieldVO.setFieldValue("");
                    fieldVO.setFieldValueDesc("");
                }
            }
            FieldEnum typeEnum = FieldEnum.parse(fieldVO.getType());
            recordToFormType(fieldVO, typeEnum);


            //添加语言包key
            Map<String, String> keyMap = LanguageFieldUtil.getFieldNameKeyMap("name_resourceKey", "customField.hrmField.", fieldVO.getFieldName(), fieldVO.getSetting());
            keyMap.put("fieldValueDesc_resourceKey", "customField.hrmField." + LanguageFieldUtil.getFieldName(fieldVO.getFieldName()) + "Options." + fieldVO.getFieldValueDesc());
            if (CollectionUtil.isNotEmpty(fieldVO.getSetting())) {
                Object first = CollectionUtil.getFirst(fieldVO.getSetting());
                if (NumberUtil.isNumber(LanguageFieldUtil.getSettingValue(first))) {

                } else {
                    keyMap.put("fieldValue_resourceKey", "customField.hrmField." + LanguageFieldUtil.getFieldName(fieldVO.getFieldName()) + "Options." + fieldVO.getFieldValueDesc());
                }
            }

            fieldVO.setLanguageKeyMap(keyMap);
            informationFieldVOList.add(fieldVO);

        });
        return informationFieldVOList;
    }

    @Override
    public HrmEmployee queryById(Long employeeId) {
        HrmEmployee employee = getById(employeeId);
        if (ObjectUtil.isNotNull(employee)) {
            hrmDeptService.lambdaQuery().select(HrmDept::getName)
                    .eq(HrmDept::getDeptId, employee.getDeptId()).oneOpt().ifPresent(dept -> employee.setDeptName(dept.getName()));
            //设置部门路径
            String path = hrmDeptService.getDeptPathByEmployeeId(employeeId);
            employee.setDeptPath(path);
            //设置职务、任职日期
            List<JSONObject> fieldDatalist = hrmEmployeeDataMapper.queryFiledListByEmployeeId(employeeId);
            //部门集合
            List<HrmDept> list = hrmDeptService.list();
            if (CollectionUtil.isNotEmpty(fieldDatalist)) {
                Map<Long, HrmDept> deptMap = list.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity(), (oldValue, newValue) -> newValue));
                Map<String, String> fieldMap = fieldDatalist.stream().collect(Collectors.toMap(fieldData -> fieldData.getString("fieldName"), fieldData -> {
                    return Optional.ofNullable(fieldData.getString("fieldValue")).orElse("");
                }, (oldValue, newValue) -> newValue));
                employee.setJobTitle(fieldMap.get("job_title"));
                employee.setDateOfEmployment(fieldMap.get("date_of_employment"));
                if (StrUtil.isNotEmpty(fieldMap.get("dept"))){
                    employee.setDeptId(Long.parseLong(fieldMap.get("dept")));
                    employee.setDeptName(Optional.ofNullable(deptMap.get(Long.parseLong(fieldMap.get("dept")))).map(HrmDept::getName).orElse(""));
                }
                if (StrUtil.isNotEmpty(fieldMap.get("org"))){
                    employee.setOrgId(Long.parseLong(fieldMap.get("org")));
                    employee.setOrgName(Optional.ofNullable(deptMap.get(Long.parseLong(fieldMap.get("org")))).map(HrmDept::getName).orElse(""));
                }
                employee.setHighestTechLevel(fieldMap.get("highest_tech_level"));
                employee.setJobLevel(fieldMap.get("job_level"));
                employee.setPolId(fieldMap.get("pol_id"));
                employee.setBirthPlace(fieldMap.get("birth_place"));
                employee.setMarriageName(fieldMap.get("marriage_name"));
                employee.setHealthName(fieldMap.get("health_name"));
                employee.setHeight(fieldMap.get("height"));
                employee.setJoinCompanyTime(fieldMap.get("join_company_time"));
                employee.setHighestDegree(fieldMap.get("highest_degree"));
            }
            //设置员工账号头像和真实姓名
            if (StrUtil.isNotEmpty(employee.getMobile())) {
                Result<EmployeeAccountInfo> accountInfoResult = adminService.getAccountInfoByUserName(employee.getMobile());
                if (accountInfoResult.hasSuccess()){
                    EmployeeAccountInfo data = accountInfoResult.getData();
                    employee.setRealName(StringUtils.isEmpty(data.getRealname()) ? employee.getEmployeeName() : data.getRealname());
                    employee.setImg(data.getImg());
                    employee.setUserId(data.getUserId());
                }
            }else {
                employee.setRealName(employee.getEmployeeName());
            }
        } else {
            log.info("当前员工查询为空,Id:{}", employeeId);
        }
        return employee;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog updateInformation(UpdateInformationBO updateInformationBO) {
        Long employeeId = updateInformationBO.getEmployeeId();
        if (employeeId == null) {
            employeeId = EmployeeHolder.getEmployeeId();
        }
        HrmEmployee oldEmployee = queryById(employeeId);

        if (updateInformationBO.getIsExamine()) {
            //保留原信息
            HrmEmployee hrmEmployee = employeeMapper.selectById(employeeId);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
            JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
            //基本信息
            List<InformationFieldVO> baseInformation = transferInformation(employeeModel, LabelGroupEnum.PERSONAL, fieldValueList);
            updateInformationBO.setOriginalDataList(baseInformation);
            //查看当前时候存在审批记录
            Boolean b = saveEmployeeInfoChangeExamine(oldEmployee, updateInformationBO);
            if (b) {
                OperationLog log = new OperationLog();
                log.setOperationInfo("提交员工信息修改审批");
                log.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());
                return log;
            }
        }
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());

        List<UpdateInformationBO.InformationFieldBO> dataList = updateInformationBO.getDataList();
        Map<FiledIsFixedEnum, List<UpdateInformationBO.InformationFieldBO>> isFixedMap = getIsFixedMap(dataList);
        List<UpdateInformationBO.InformationFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), employeeData.getFieldValue()));
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        employee.setEmployeeId(employeeId);
        if (employee.getIdType() != null && employee.getIdType() == IdTypeEnum.ID_CARD.getValue() && StrUtil.isNotEmpty(employee.getIdNumber())) {
            String idNumber = employee.getIdNumber();
            if (!IdcardUtil.isValidCard(idNumber)) {
                throw new CrmException(HrmCodeEnum.IDENTITY_INFORMATION_IS_ILLEGAL, idNumber);
            }
            employee.setDateOfBirth(IdcardUtil.getBirthDate(idNumber).toLocalDateTime().toLocalDate());
        }
        if (ObjectUtil.isNotNull(employee.getDateOfBirth())) {
            if (employee.getDateOfBirth().isBefore(LocalDate.now())) {
                employee.setAge(DateUtil.ageOfNow(LocalDateTimeUtil.format(employee.getDateOfBirth(), DatePattern.NORM_DATE_PATTERN)));
            }
        }
        boolean jobCount = lambdaQuery().eq(HrmEmployee::getJobNumber, employee.getJobNumber()).ne(HrmEmployee::getEmployeeId, employee.getEmployeeId())
                .eq(HrmEmployee::getIsDel, 0).exists();
        if (jobCount) {
            throw new CrmException(HrmCodeEnum.JOB_NUMBER_EXISTED);
        }
        boolean mobileCount = lambdaQuery().eq(HrmEmployee::getMobile, employee.getMobile()).ne(HrmEmployee::getEmployeeId, employee.getEmployeeId())
                .eq(HrmEmployee::getIsDel, 0).exists();
        if (mobileCount) {
            throw new CrmException(HrmCodeEnum.PHONE_NUMBER_ALREADY_EXISTS, employee.getMobile());
        }
        List<UpdateInformationBO.InformationFieldBO> informationFieldBOS = isFixedMap.get(FiledIsFixedEnum.NO_FIXED);
        List<HrmEmployeeData> hrmEmployeeData = informationFieldBOS.stream()
                .map(field -> {
                    Object value = field.getFieldValue();
                    if (value == null) {
                        value = "";
                    }
                    field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                    return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                }).collect(Collectors.toList());
        Dict kv = Dict.create().set("key", "employee_id").set("param", "label_group").set("labelGroup", LabelGroupEnum.PERSONAL.getValue()).set("value", employeeId).set("dataTableName", "wk_hrm_employee_data");
        List<HrmModelFiledVO> oldFieldList = ApplicationContextHolder.getBean(IHrmActionRecordService.class).queryFieldValue(kv);
        employeeFieldService.saveEmployeeField(hrmEmployeeData, LabelGroupEnum.PERSONAL, employeeId);
        if (employee.getDateOfBirth() == null) {
            lambdaUpdate().eq(HrmEmployee::getEmployeeId, employeeId).set(HrmEmployee::getDateOfBirth, null).update();
        }
        if (ObjectUtil.isNotNull(employee.getCompanyAgeStartTime())) {
            long nowCompanyAge = LocalDateTimeUtil.between(employee.getCompanyAgeStartTime().atStartOfDay(), LocalDateTime.now()).toDays() + 1;
            employee.setCompanyAge(Convert.toInt(nowCompanyAge));
        }
        //更新sortId
        updateDeptEmployeeSortId(employee);
        updateById(employee);
        if (ObjectUtil.isNotNull(oldEmployee)) {
            //固定字段操作记录保存
            Content content = employeeActionRecordService.employeeFixedFieldRecord(BeanUtil.beanToMap(oldEmployee), BeanUtil.beanToMap(employee), LabelGroupEnum.PERSONAL, employeeId);
            //非固定字段操作记录保存

            String[] recprdInfo = content.getDetail().split(",");

            Content content1 = employeeActionRecordService.employeeNOFixedFieldRecord(informationFieldBOS, oldFieldList, employeeId);

            String[] recprdInfo1 = content1.getDetail().split(",");

            String[] updateInfo = ArrayUtil.addAll(recprdInfo, recprdInfo1);
            operationLog.setOperationInfo(JSONUtil.toJsonStr(updateInfo));
        }
        //更新es员工数据
        updateESAfterCommit(employeeId);
        if (EmployeeHolder.getEmployeeInfo() != null){
            //保存员工修改记录
            HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
            record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
            record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
            record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
            record.setEmployeeId(employeeId);
            record.setRemark(String.format("员工 %s 编辑了 %s 基本信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
            employeeDataChangeRecordService.addChangeRecord(record);
        }
        return operationLog;
    }

    @Override
    @Transactional
    public OperationLog updateKeyFieldAudit(Map<String, UpdateInformationBO> informationBOMap) {
        UpdateInformationBO postParams = informationBOMap.get("postParams");
        UpdateInformationBO baseParams = informationBOMap.get("baseParams");
        List<UpdateInformationBO.InformationFieldBO> dataList = postParams.getDataList();
        if (dataList != null) {
            List<HrmDept> deptList = hrmDeptService.lambdaQuery().list();
            Map<Long, HrmDept> deptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity()));
            dataList.forEach(employeeData -> {
                if (employeeData.getFieldValue() != null){
                    if ("dept".equals(employeeData.getFieldName())) {
                        String deptStr = employeeData.getFieldValue().toString();
                        HrmDept hrmDept = deptMap.get(Long.parseLong(deptStr));
                        if (hrmDept != null && hrmDept.getDeptType() != 2){
                            throw new CrmException(HrmCodeEnum.THE_DEPARTMENT_SELECTION_ERROR);
                        }
                        long deptId = Long.parseLong(employeeData.getFieldValue().toString());
                        if (deptMap.containsKey(deptId)) {
                            employeeData.setFieldValueDesc(deptMap.get(deptId).getName());
                        }
                    }else if ("org".equals(employeeData.getFieldName())) {
                        String deptStr = employeeData.getFieldValue().toString();
                        HrmDept hrmDept = deptMap.get(Long.parseLong(deptStr));
                        if (hrmDept != null && hrmDept.getDeptType() != 1){
                            throw new CrmException(HrmCodeEnum.THE_ORG_SELECTION_ERROR);
                        }
                        long orgId = Long.parseLong(employeeData.getFieldValue().toString());
                        if (deptMap.containsKey(orgId)) {
                            employeeData.setFieldValueDesc(deptMap.get(orgId).getName());
                        }
                    }else if ("post_status".equals(employeeData.getFieldName())){
                        if (!UserUtil.isAdmin() && employeeData.getFieldValue().toString().equals(HrmPostStatusEnum.RETIRE.getName())){
                            throw new CrmException(HrmCodeEnum.POST_STATUS_UPDATE_ERROR);
                        }
                    }
                }
            });
        }
        OperationLog log = new OperationLog();
        Long employeeId = postParams.getEmployeeId();
        HrmEmployee oldEmployee = queryById(employeeId);
        //TODO 先设置为集团总部审核
        oldEmployee.setOrgId(OrgConstant.GROUP_ORG_ID);
        //查看当前时候存在审批记录
        HashMap<String, Object> map = new HashMap<>();
        map.put("employeeId", employeeId);
        map.put("postParams", postParams);
        map.put("baseParams", baseParams);
        //审批显示原信息
        PersonalInformationAndPostVO personalInformationAndPostVO = personalInformationAndPost(employeeId);
        map.put("originallyBase", personalInformationAndPostVO.getBaseInformation());
        map.put("originallyPost", personalInformationAndPostVO.getPostInformation());
        Boolean b = saveEmployeeKeyFieldChangeExamine(oldEmployee, map);
        if (b) {
            log.setOperationInfo("提交员工关键字段修改审批");
            log.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());
            return log;
        }
        this.updateInformation(baseParams);
        employeePostService.updatePostInformation(postParams);
        log.setOperationInfo("提交员工关键字段修改审批");
        log.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());
        return log;
    }

    @Override
    public PersonalInformationAndPostVO personalInformationAndPost(Long employeeId) {

        HrmEmployee hrmEmployee = employeeMapper.selectById(employeeId);
        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
        JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
        //基本信息
        List<InformationFieldVO> baseInformation = transferInformation(employeeModel, LabelGroupEnum.PERSONAL, fieldValueList);
        //岗位信息
        List<InformationFieldVO> postInformation = this.transferInformation(employeeModel, LabelGroupEnum.POST, fieldValueList);

        return new PersonalInformationAndPostVO(baseInformation, postInformation);
    }

    @Override
    public EmployeeCurrentWorkExperienceVo queryCurrentWorkExperience(Long employeeId) {
        return employeeMapper.queryCurrentWorkExperience(employeeId);
    }

    @Override
    @Transactional
    public OperationLog updatePostLevelAudit(EmployeePostLevelVo employeePostLevelVo) {
        if (employeePostLevelVo.getOldPostLevel() == null || employeePostLevelVo.getNewPostLevel() == null ||
                employeePostLevelVo.getEmployeeId() == null){
            throw new CrmException(SystemCodeEnum.SYSTEM_NO_VALID);
        }
        if (employeePostLevelVo.getOldPostLevel().equals(employeePostLevelVo.getNewPostLevel())){
            throw new CrmException(HrmCodeEnum.POST_LEVEL_UPDATE_ERROR);
        }
        HrmJobLevelEnum newPostLevel = HrmJobLevelEnum.parse(employeePostLevelVo.getNewPostLevel());
        HrmJobLevelEnum oldPostLevel = HrmJobLevelEnum.parse(employeePostLevelVo.getOldPostLevel());
        if (newPostLevel.getLevel() <= HrmJobLevelEnum.TWELVE.getLevel() && newPostLevel.getLevel() < oldPostLevel.getLevel()){
            HrmEmployee oldEmployee = queryById(employeePostLevelVo.getEmployeeId());
            //TODO 先设置为集团总部审核
            oldEmployee.setOrgId(OrgConstant.GROUP_ORG_ID);
            //执行审批流程
            Boolean b = saveEmployeePostLevelChangeExamine(oldEmployee, employeePostLevelVo);
            if (b) {
                OperationLog log = new OperationLog();
                log.setOperationInfo("职位层级调整审批提交成功");
                log.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());
                return log;
            }
        }
        //保存员工资料附件
        List<EmployeeMaterialBO> materialList = employeePostLevelVo.getMaterialList();
        if (materialList != null && !materialList.isEmpty()){
            for (EmployeeMaterialBO materialBO : materialList) {
                AddFileBO addFileBO = new AddFileBO();
                addFileBO.setEmployeeId(employeePostLevelVo.getEmployeeId());
                addFileBO.setSubType(materialBO.getSubType());
                addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                hrmEmployeeFileService.addFile(addFileBO);
            }
        }
        changeEmployeeData(LocalDate.now().toString(), employeePostLevelVo.getEmployeeId(), "date_of_employment_level");
        return this.updateEmployeePostLevel(employeePostLevelVo);
    }

    private void changeEmployeeData(String value, Long employeeId, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, employeeId);
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            hrmEmployeeData.setFieldValue(value);
            hrmEmployeeData.setFieldValueDesc(value);
            hrmEmployeeData.setEmployeeId(employeeId);
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }

    @Override
    @Transactional
    public OperationLog updateEmployeePostLevel(EmployeePostLevelVo employeePostLevelVo) {
        employeeDataService.lambdaUpdate().eq(HrmEmployeeData::getEmployeeId, employeePostLevelVo.getEmployeeId())
                .eq(HrmEmployeeData::getFieldName, "job_level").remove();

        HrmEmployeeField field = employeeFieldService.lambdaQuery().eq(HrmEmployeeField::getFieldName, "job_level")
                .eq(HrmEmployeeField::getLabelGroup, LabelGroupEnum.POST.getValue())
                .eq(HrmEmployeeField::getLabel, 2).one();
        HrmEmployeeData data = new HrmEmployeeData();
        data.setFieldId(field.getFieldId());
        data.setFieldName("job_level");
        data.setLabelGroup(LabelGroupEnum.POST.getValue());
        data.setName(field.getName());
        data.setFieldValue(employeePostLevelVo.getNewPostLevel());
        data.setFieldValueDesc(employeePostLevelVo.getNewPostLevel());
        data.setEmployeeId(employeePostLevelVo.getEmployeeId());
        employeeDataService.save(data);
        HrmEmployee employee = queryById(employeePostLevelVo.getEmployeeId());
        OperationLog log = new OperationLog();
        log.setOperationInfo("职位层级调整修改成功");
        log.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        updateESAfterCommit(employeePostLevelVo.getEmployeeId());
        return log;
    }

    private void updateDeptEmployeeSortId(HrmEmployee employee){
        if (employee.getSortId() != null){
            Long deptId = hrmDeptService.getEmployeeDeptId(employee.getEmployeeId(), "dept");
            if (deptId != null){
                HrmEmployee emp = new HrmEmployee();
                emp.setDeptId(deptId);
                emp.setSortId(employee.getSortId());
                employeeMapper.updateEmployeeSortById(emp);
            }
        }
    }

    private <E> Map<FiledIsFixedEnum, List<E>> getIsFixedMap(List<E> dataList) {
        Map<FiledIsFixedEnum, List<E>> listMap =
                dataList.stream().collect(Collectors.groupingBy(employeeData -> {
                    if (employeeData instanceof UpdateInformationBO.InformationFieldBO) {
                        return FiledIsFixedEnum.parse(((UpdateInformationBO.InformationFieldBO) employeeData).getIsFixed());
                    } else if (employeeData instanceof AddEmployeeFieldManageBO.EmployeeFieldBO) {
                        return FiledIsFixedEnum.parse(((AddEmployeeFieldManageBO.EmployeeFieldBO) employeeData).getIsFixed());
                    }
                    return FiledIsFixedEnum.FIXED;
                }));
        if (!listMap.containsKey(FiledIsFixedEnum.FIXED)) {
            listMap.put(FiledIsFixedEnum.FIXED, new ArrayList<>());
        }
        if (!listMap.containsKey(FiledIsFixedEnum.NO_FIXED)) {
            listMap.put(FiledIsFixedEnum.NO_FIXED, new ArrayList<>());
        }
        return listMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog updateCommunication(UpdateInformationBO updateInformationBO) {
        Long employeeId = updateInformationBO.getEmployeeId();
        if (employeeId == null) {
            employeeId = EmployeeHolder.getEmployeeId();
        }
        HrmEmployee oldEmployee = queryById(employeeId);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(oldEmployee.getEmployeeId(), oldEmployee.getEmployeeName());


        List<UpdateInformationBO.InformationFieldBO> dataList = updateInformationBO.getDataList();
        Map<FiledIsFixedEnum, List<UpdateInformationBO.InformationFieldBO>> isFixedMap = getIsFixedMap(dataList);
        List<UpdateInformationBO.InformationFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), employeeData.getFieldValue()));
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        employee.setEmployeeId(employeeId);
        updateById(employee);
        List<UpdateInformationBO.InformationFieldBO> informationFieldBOS = isFixedMap.get(FiledIsFixedEnum.NO_FIXED);
        List<HrmEmployeeData> hrmEmployeeData = informationFieldBOS.stream()
                .map(field -> {
                    Object value = field.getFieldValue();
                    if (value == null) {
                        value = "";
                    }
                    field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                    return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                }).collect(Collectors.toList());
        Dict set = Dict.create().set("key", "employee_id").set("value", employeeId).set("param", "label_group").set("labelGroup", LabelGroupEnum.CONTACT_PERSON.getValue()).set("dataTableName", "wk_hrm_employee_data");
        List<HrmModelFiledVO> oldFieldList = ApplicationContextHolder.getBean(IHrmActionRecordService.class).queryFieldValue(set);
        employeeFieldService.saveEmployeeField(hrmEmployeeData, LabelGroupEnum.CONTACT_PERSON, employeeId);
        //固定字段操作记录保存
        Content content = employeeActionRecordService.employeeFixedFieldRecord(BeanUtil.beanToMap(oldEmployee), BeanUtil.beanToMap(employee), LabelGroupEnum.CONTACT_PERSON, employeeId);
        //非固定字段操作记录保存
        Content content1 = employeeActionRecordService.employeeNOFixedFieldRecord(informationFieldBOS, oldFieldList, employeeId);
        String[] split = content.getDetail().split(",");
        String[] split1 = content1.getDetail().split(",");
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ArrayUtil.addAll(split, split1)));
        //更新es员工数据
        updateESAfterCommit(employeeId);
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employeeId);
        record.setRemark(String.format("员工 %s 编辑了 %s 紧急联系人信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), oldEmployee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateEduExperience(HrmEmployeeEducationExperience educationExperience) {
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = getById(educationExperience.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (educationExperience.getEducationId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.EDUCATIONAL_EXPERIENCE, educationExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        } else {
            HrmEmployeeEducationExperience old = educationExperienceService.getById(educationExperience.getEducationId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.EDUCATIONAL_EXPERIENCE, BeanUtil.beanToMap(old), BeanUtil.beanToMap(educationExperience), educationExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        educationExperienceService.saveOrUpdate(educationExperience);
        //更新es员工数据
        updateESAfterCommit(educationExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (educationExperience.getEducationId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 教育经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 教育经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteEduExperience(Long educationId) {
        HrmEmployeeEducationExperience educationExperience = educationExperienceService.getById(educationId);
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = getById(educationExperience.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.EDUCATIONAL_EXPERIENCE, educationExperience.getEmployeeId());

        operationLog.setOperationInfo(content.getDetail());
        educationExperienceService.removeById(educationId);
        //更新es员工数据
        updateESAfterCommit(educationExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 教育经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateWorkExperience(HrmEmployeeWorkExperience workExperience) {
        HrmEmployee employee = getById(workExperience.getEmployeeId());

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (workExperience.getWorkExpId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.WORK_EXPERIENCE, workExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        } else {
            HrmEmployeeWorkExperience old = workExperienceService.getById(workExperience.getWorkExpId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.WORK_EXPERIENCE, BeanUtil.beanToMap(old), BeanUtil.beanToMap(workExperience), workExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        //TODO 操作记录
        workExperienceService.saveOrUpdate(workExperience);
        //更新es员工数据
        updateESAfterCommit(workExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (workExperience.getWorkExpId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 工作经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 工作经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteWorkExperience(Long workExpId) {
        HrmEmployeeWorkExperience workExperience = workExperienceService.getById(workExpId);

        HrmEmployee employee = getById(workExperience.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.WORK_EXPERIENCE, workExperience.getEmployeeId());
        operationLog.setOperationInfo(content.getDetail());
        workExperienceService.removeById(workExpId);
        //更新es员工数据
        updateESAfterCommit(workExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 工作经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateCertificate(HrmEmployeeCertificate certificate) {
        HrmEmployee employee = getById(certificate.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (certificate.getCertificateId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.CERTIFICATE, certificate.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));

        } else {
            HrmEmployeeCertificate old = certificateService.getById(certificate.getCertificateId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.CERTIFICATE, BeanUtil.beanToMap(old), BeanUtil.beanToMap(certificate), certificate.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        certificateService.saveOrUpdate(certificate);
        //更新es员工数据
        updateESAfterCommit(certificate.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (certificate.getCertificateId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 职（执）业资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 职（执）业资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteCertificate(Long certificateId) {

        HrmEmployeeCertificate certificate = certificateService.getById(certificateId);
        HrmEmployee employee = getById(certificate.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.CERTIFICATE, certificate.getEmployeeId());
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        certificateService.removeById(certificateId);
        //更新es员工数据
        updateESAfterCommit(certificate.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 职（执）业资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateTechnical(HrmEmployeeTechnical technical) {
        HrmEmployee employee = getById(technical.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (technical.getTechnicalId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.TECHNICAL, technical.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));

        } else {
            HrmEmployeeTechnical old = technicalService.getById(technical.getTechnicalId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.TECHNICAL, BeanUtil.beanToMap(old), BeanUtil.beanToMap(technical), technical.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        technicalService.saveOrUpdate(technical);
        //更新es员工数据
        updateESAfterCommit(technical.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (technical.getTechnicalId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 专业技术资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 专业技术资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteTechnical(Long technicalId) {

        HrmEmployeeTechnical technical = technicalService.getById(technicalId);
        HrmEmployee employee = getById(technical.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.TECHNICAL, technical.getEmployeeId());
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        technicalService.removeById(technicalId);
        //更新es员工数据
        updateESAfterCommit(technical.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 专业技术资格。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateSpecialWorker(HrmEmployeeSpecialWorker specialWorker) {
        HrmEmployee employee = getById(specialWorker.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (specialWorker.getSpecialWorkerId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.SPECIAL_WORKER, specialWorker.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));

        } else {
            HrmEmployeeSpecialWorker old = specialWorkerService.getById(specialWorker.getSpecialWorkerId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.SPECIAL_WORKER, BeanUtil.beanToMap(old), BeanUtil.beanToMap(specialWorker), specialWorker.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        specialWorkerService.saveOrUpdate(specialWorker);
        //更新es员工数据
        updateESAfterCommit(specialWorker.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (specialWorker.getSpecialWorkerId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 专业技术工人证书。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 专业技术工人证书。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteSpecialWorker(Long specialWorkerId) {

        HrmEmployeeSpecialWorker specialWorker = specialWorkerService.getById(specialWorkerId);
        HrmEmployee employee = getById(specialWorker.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.SPECIAL_WORKER, specialWorker.getEmployeeId());
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        specialWorkerService.removeById(specialWorkerId);
        //更新es员工数据
        updateESAfterCommit(specialWorker.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 专业技术工人证书。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateTrainingExperience(HrmEmployeeTrainingExperience trainingExperience) {

        HrmEmployee employee = getById(trainingExperience.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        if (trainingExperience.getTrainingId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.TRAINING_EXPERIENCE, trainingExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        } else {
            HrmEmployeeTrainingExperience old = trainingExperienceService.getById(trainingExperience.getTrainingId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.TRAINING_EXPERIENCE, BeanUtil.beanToMap(old), BeanUtil.beanToMap(trainingExperience), trainingExperience.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));

        }
        trainingExperienceService.saveOrUpdate(trainingExperience);
        //更新es员工数据
        updateESAfterCommit(trainingExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (trainingExperience.getTrainingId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 培训经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 培训经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteTrainingExperience(Long trainingId) {
        HrmEmployeeTrainingExperience trainingExperience = trainingExperienceService.getById(trainingId);
        HrmEmployee employee = getById(trainingExperience.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.TRAINING_EXPERIENCE, trainingExperience.getEmployeeId());
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        trainingExperienceService.removeById(trainingId);
        //更新es员工数据
        updateESAfterCommit(trainingExperience.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 培训经历。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    public List<HrmEmployeeField> queryContactsAddField() {
        return employeeFieldService.queryInformationFieldByLabelGroup(LabelGroupEnum.CONTACT_PERSON);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateContacts(UpdateInformationBO updateInformationBO) {
        Long contactsId = updateInformationBO.getContactsId();
        HrmEmployeeContacts oldEmployeeContacts = contactsService.getById(contactsId);
        Long employeeId = updateInformationBO.getEmployeeId();
        List<UpdateInformationBO.InformationFieldBO> fieldList = updateInformationBO.getDataList();
        Map<FiledIsFixedEnum, List<UpdateInformationBO.InformationFieldBO>> isFixedMap = getIsFixedMap(fieldList);
        List<UpdateInformationBO.InformationFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(contactsData -> jsonObject.put(contactsData.getFieldName(), FieldUtil.convertFieldValue(contactsData.getType(), contactsData.getFieldValue(), IsEnum.YES.getValue())));
        HrmEmployeeContacts employeeContacts = jsonObject.toJavaObject(HrmEmployeeContacts.class);
        employeeContacts.setEmployeeId(employeeId);
        employeeContacts.setContactsId(contactsId);

        HrmEmployee employee = getById(employeeContacts.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        if (employeeContacts.getContactsId() == null) {
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.CONTACT_PERSON, employeeContacts.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));

        } else {
            //固定字段操作记录保存
            Content content = employeeActionRecordService.employeeFixedFieldRecord(BeanUtil.beanToMap(oldEmployeeContacts), BeanUtil.beanToMap(employeeContacts), LabelGroupEnum.CONTACT_PERSON, employeeId);
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        contactsService.saveOrUpdate(employeeContacts);
        List<UpdateInformationBO.InformationFieldBO> informationFieldBOS = isFixedMap.get(FiledIsFixedEnum.NO_FIXED);
        if (null != informationFieldBOS && informationFieldBOS.size() > 0) {
            List<HrmEmployeeContactsData> hrmEmployeeContactsData = informationFieldBOS.stream()
                    .map(field -> {
                        Object value = field.getFieldValue();
                        if (value == null) {
                            value = "";
                        }
                        field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                        return BeanUtil.copyProperties(field, HrmEmployeeContactsData.class);
                    }).collect(Collectors.toList());
            Dict set = Dict.create().set("key", "contacts_id").set("value", contactsId).set("param", "label_group").set("labelGroup", LabelGroupEnum.CONTACT_PERSON.getValue()).set("dataTableName", "wk_hrm_employee_contacts_data");
            List<HrmModelFiledVO> oldFieldList = ApplicationContextHolder.getBean(IHrmActionRecordService.class).queryFieldValue(set);
            employeeFieldService.saveEmployeeContactsField(hrmEmployeeContactsData, LabelGroupEnum.CONTACT_PERSON, employeeContacts.getContactsId());
            //非固定字段操作记录保存
            employeeActionRecordService.employeeNOFixedFieldRecord(informationFieldBOS, oldFieldList, employeeId);
            //更新es员工数据
            updateESAfterCommit(employeeId);
            //保存员工修改记录
            HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
            record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
            record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
            record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
            record.setEmployeeId(employee.getEmployeeId());
            if (updateInformationBO.getContactsId() == null) {
                record.setRemark(String.format("员工 %s 新建了 %s 家庭成员及主要社会关系。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
            } else {
                record.setRemark(String.format("员工 %s 修改了 %s 家庭成员及主要社会关系。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
            }
            employeeDataChangeRecordService.addChangeRecord(record);
        }
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteContacts(Long contractsId) {
        HrmEmployeeContacts employeeContacts = contactsService.getById(contractsId);

        HrmEmployee employee = getById(employeeContacts.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.CONTACT_PERSON, employeeContacts.getEmployeeId());
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        contactsService.removeById(contractsId);
        contactsDataService.lambdaUpdate().eq(HrmEmployeeContactsData::getContactsId, contractsId).remove();
        //更新es员工数据
        updateESAfterCommit(employee.getEmployeeId());
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 家庭成员及主要社会关系。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        return operationLog;
    }

    @Override
    public List<OperationLog> deleteByIds(List<Long> employeeIds) {
        List<HrmEmployee> hrmEmployees = listByIds(employeeIds);
        List<OperationLog> operationLogList = new ArrayList<>();
        for (HrmEmployee hrmEmployee : hrmEmployees) {
            OperationLog operationLog = new OperationLog();
            operationLog.setOperationObject(hrmEmployee.getEmployeeId(), hrmEmployee.getEmployeeName());
            operationLog.setOperationInfo("删除了员工" + hrmEmployee.getEmployeeName());
            operationLogList.add(operationLog);
            //保存员工修改记录
            HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
            record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
            record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
            record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
            record.setEmployeeId(hrmEmployee.getEmployeeId());
            record.setRemark(String.format("员工 %s 删除了员工 %s 。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), hrmEmployee.getEmployeeName()));
            employeeDataChangeRecordService.addChangeRecord(record);
        }
        lambdaUpdate().set(HrmEmployee::getIsDel, 1).in(HrmEmployee::getEmployeeId, employeeIds).update();
        abnormalChangeRecordService.lambdaUpdate().in(HrmEmployeeAbnormalChangeRecord::getEmployeeId, employeeIds).remove();
        //更新es中数据
        EsUtil.deleteData(employeeIds,HrmElasticSearchIndexEnum.EMPLOYEE);
        return operationLogList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog change(HrmEmployeeChangeRecord hrmEmployeeChangeRecord) {
        List<HrmDept> deptList = hrmDeptService.lambdaQuery().list();
        Map<Long, HrmDept> deptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity()));
        if (hrmEmployeeChangeRecord.getNewDept() != null && deptMap.containsKey(hrmEmployeeChangeRecord.getNewDept())) {
            HrmDept hrmDept = deptMap.get(hrmEmployeeChangeRecord.getNewDept());
            if (hrmDept.getDeptType() != 2) {
                throw new CrmException(HrmCodeEnum.THE_DEPARTMENT_SELECTION_ERROR);
            }
        }
        if (hrmEmployeeChangeRecord.getNewOrg() != null && deptMap.containsKey(hrmEmployeeChangeRecord.getNewOrg())) {
            HrmDept hrmDept = deptMap.get(hrmEmployeeChangeRecord.getNewOrg());
            if (hrmDept.getDeptType() != 1) {
                throw new CrmException(HrmCodeEnum.THE_ORG_SELECTION_ERROR);
            }
        }
        HrmEmployee employee = getById(hrmEmployeeChangeRecord.getEmployeeId());
        List<JSONObject> fieldDatalist = employeeDataService.queryFiledListByEmployeeId(employee.getEmployeeId());
        List<JSONObject> orgField = fieldDatalist.stream().filter(o -> o.getString("fieldName").equals("org")).collect(Collectors.toList());
        List<JSONObject> deptField = fieldDatalist.stream().filter(o -> o.getString("fieldName").equals("dept")).collect(Collectors.toList());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        if (hrmEmployeeChangeRecord.getChangeType() != HrmActionBehaviorEnum.BECOME.getValue()) {
            if(ObjectUtils.isNotEmpty(orgField)){
                hrmEmployeeChangeRecord.setOldOrg(orgField.get(0).getLong("fieldValue"));
            }
            if(ObjectUtils.isNotEmpty(deptField)){
                hrmEmployeeChangeRecord.setOldDept(deptField.get(0).getLong("fieldValue"));
            }
            hrmEmployeeChangeRecord.setOldParentId(employee.getParentId());
//            hrmEmployeeChangeRecord.setOldPost(employee.getPost());
//            hrmEmployeeChangeRecord.setOldPostLevel(employee.getPostLevel());
            hrmEmployeeChangeRecord.setOldWorkAddress(employee.getWorkAddress());
        }
        HrmEmployee hrmEmployee = EmployeeChangeCron.employeeChangeRecord(hrmEmployeeChangeRecord);
        //大于当前或等于当前时间才需要审核 TODO 取消限制
        Boolean res = false;
//        if (LocalDateTimeUtil.toEpochMilli(hrmEmployeeChangeRecord.getEffectTime()) >= System.currentTimeMillis()) {
        // 将新创建的异动记录放入缓存，设置60秒过期
        String cacheKey = CrmCacheKey.EXAMINE_CHANGE_RECORD_TEMP_CACHE_KEY + hrmEmployeeChangeRecord.getEmployeeId();
        BaseUtil.getRedis().setex(cacheKey, 60, JSON.toJSONString(hrmEmployeeChangeRecord));
            //新增调动流程，看是否成功，如果成功，证明存在examine
            res = this.saveChangeExamine(hrmEmployee.getEmployeeId(),hrmEmployeeChangeRecord);
//        }
        //保存部门和机构的数据:无需审核 或者 未找到流程。
        if(!res){
            if (!hrmEmployeeChangeRecord.getNewOrg().equals(hrmEmployeeChangeRecord.getOldOrg())){
                hrmEmployee.setCompanyAgeStartTime(LocalDate.now());
            }
            this.saveOrUpdate(hrmEmployee);
            //生效时间是当前或者之前 直接修改员工状态，员工的变动记录也提前生成
            if (hrmEmployeeChangeRecord.getNewDept() != null) {
                changeDept(hrmEmployeeChangeRecord,"dept");
            }
            if (hrmEmployeeChangeRecord.getNewOrg() != null) {
                changeDept(hrmEmployeeChangeRecord,"org");
            }
            if (StrUtil.isNotBlank(hrmEmployeeChangeRecord.getNewPost())) {
                changeEmployeePost(hrmEmployeeChangeRecord,"job_title");
            }
            if (StrUtil.isNotBlank(hrmEmployeeChangeRecord.getNewPostLevel())) {
                changeEmployeePost(hrmEmployeeChangeRecord,"job_level");
            }
            if (ObjectUtil.isNotEmpty(hrmEmployeeChangeRecord.getNewPostLevel()) && !Objects.equals(hrmEmployeeChangeRecord.getOldPostLevel(), hrmEmployeeChangeRecord.getNewPostLevel())){
                //更新员工职位层级
                changeEmployeeData(LocalDate.now().toString(), hrmEmployee.getEmployeeId(), "date_of_employment_level");
            }
            if (hrmEmployeeChangeRecord.getNewDept() != null && hrmEmployeeChangeRecord.getNewOrg() != null){
                //更新员工任职日期
                changeEmployeeData(LocalDate.now().toString(), hrmEmployee.getEmployeeId(), "date_of_employment");
            }
            //保存移动材料
            List<EmployeeMaterialBO> materialList = hrmEmployeeChangeRecord.getMaterialList();
            if (materialList != null && !materialList.isEmpty()){
                for (EmployeeMaterialBO materialBO : materialList) {
                    AddFileBO addFileBO = new AddFileBO();
                    addFileBO.setEmployeeId(employee.getEmployeeId());
                    addFileBO.setSubType(materialBO.getSubType());
                    addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                    hrmEmployeeFileService.addFile(addFileBO);
                }
            }
        }
        //添加异动记录
        if (hrmEmployeeChangeRecord.getChangeType() == HrmActionBehaviorEnum.BECOME.getValue()) {
            lambdaUpdate().set(HrmEmployee::getBecomeTime, hrmEmployeeChangeRecord.getEffectTime()).eq(HrmEmployee::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId())
                    .update();
            abnormalChangeRecordService.addAbnormalChangeRecord(hrmEmployeeChangeRecord.getEmployeeId(), AbnormalChangeType.BECOME, hrmEmployeeChangeRecord.getEffectTime().atStartOfDay());
        } else if (hrmEmployeeChangeRecord.getChangeType() == HrmActionBehaviorEnum.CHANGE_POST.getValue()) {
            abnormalChangeRecordService.addAbnormalChangeRecord(hrmEmployeeChangeRecord.getEmployeeId(), AbnormalChangeType.CHANGE_POST, hrmEmployeeChangeRecord.getEffectTime().atStartOfDay());
        }
        changeRecordService.saveOrUpdate(hrmEmployeeChangeRecord);
        Content content = employeeActionRecordService.changeRecord(hrmEmployeeChangeRecord);
        operationLog.setOperationInfo(content.getDetail());
        //保存员工异动记录
        HrmEmployeeDataMobilizeRecord record = new HrmEmployeeDataMobilizeRecord();
        record.setEmployeeId(employee.getEmployeeId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setType(EmployeeDataMobilizeType.MOBILIZE.getValue());
        record.setRemark(String.format("员工 %s 办理了 %s 的人员调动。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        hrmEmployeeDataMobilizeRecordService.addMobilizeRecord(record);
        //更新es员工数据
        updateESAfterCommit(employee.getEmployeeId());
        return operationLog;
    }
    private void changeEmployeePost(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            if ("job_level".equals(fieldName)){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
            }else if ("job_title".equals(fieldName)){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
            }
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }
    private void changeDept(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            if(fieldName.equals("org")){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewOrg()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewOrg()));
            }
            if(fieldName.equals("dept")){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
            }
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }


    @Override
    public List<OperationLog> updateInsuranceScheme(UpdateInsuranceSchemeBO updateInsuranceSchemeBO) {
        List<OperationLog> operationLogList = new ArrayList<>();

        updateInsuranceSchemeBO.getEmployeeIds().forEach(employeeId -> {
            Long schemeId = updateInsuranceSchemeBO.getSchemeId();
            HrmEmployee employee = getById(employeeId);
            OperationLog operationLog = new OperationLog();
            operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

            Optional<HrmEmployeeSocialSecurityInfo> socialSecurityInfoOpt = securityInfoService.lambdaQuery()
                    .eq(HrmEmployeeSocialSecurityInfo::getEmployeeId, employeeId).oneOpt();
            Long oldSchemeId = null;
            if (socialSecurityInfoOpt.isPresent()) {
                HrmEmployeeSocialSecurityInfo socialSecurityInfo = socialSecurityInfoOpt.get();
                oldSchemeId = socialSecurityInfo.getSchemeId();
                securityInfoService.lambdaUpdate().set(HrmEmployeeSocialSecurityInfo::getSchemeId, schemeId).eq(HrmEmployeeSocialSecurityInfo::getEmployeeId, employeeId).update();
            } else {
                HrmEmployeeSocialSecurityInfo socialSecurityInfo = new HrmEmployeeSocialSecurityInfo();
                socialSecurityInfo.setSchemeId(schemeId);
                socialSecurityInfo.setEmployeeId(employeeId);
                securityInfoService.save(socialSecurityInfo);
            }
            if (oldSchemeId == null || !oldSchemeId.equals(schemeId)) {
                HrmInsuranceScheme oldInsuranceScheme = insuranceSchemeService.getById(oldSchemeId);
                HrmInsuranceScheme newInsuranceScheme = insuranceSchemeService.getById(schemeId);
                Content content = employeeActionRecordService.updateSchemeRecord(oldInsuranceScheme, newInsuranceScheme, employee);
                operationLog.setOperationInfo(content.getDetail());
                operationLogList.add(operationLog);
            }
        });
        return operationLogList;
    }


    @Override
    public Map<String, Object> queryEmployeeDetailById(Long empId) {
        Map<String, Object> map = employeeMapper.queryEmployeeDetailById(empId);
        if (map != null) {
            map.remove("deptName");
            map.remove("deptId");
            Long employeeId = Convert.toLong(map.get("employeeId"));
            List<JSONObject> fieldDatalist = employeeDataService.queryFiledListByEmployeeId(employeeId);
            for (JSONObject fieldData : fieldDatalist) {
                if (StringUtils.isEmpty(fieldData.getString("fieldName"))) {
                    continue;
                }
                Object value = employeeFieldService
                        .convertValueByFormType(fieldData.getString("fieldValue"),
                                FieldEnum.parse(Integer.valueOf(fieldData.getString("type"))));
                map.put(StrUtil.toCamelCase(fieldData.getString("fieldName")), value);
            }
            String keyName = "joinCompanyTime";
            if (map.get(keyName) != null && ObjectUtil.notEqual(Convert.toInt(map.get("entryStatus")), EmployeeEntryStatusEnum.已离职.getValue())) {
                LocalDateTime companyAgeStartTime = LocalDateTimeUtil.parse((String) map.get("joinCompanyTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                if (companyAgeStartTime != null) {
                    long nowCompanyAge = LocalDateTimeUtil.between(companyAgeStartTime, LocalDateTime.now()).toDays() + 1;
                    if (LocalDateTimeUtil.toEpochMilli(companyAgeStartTime) > System.currentTimeMillis()) {
                        nowCompanyAge = 0;
                    }
                    map.put("companyAge", EmployeeUtil.computeCompanyAge((int) nowCompanyAge));
                }
            }
            if (map.get("dept") != null && CollUtil.isNotEmpty(Convert.toList(SimpleHrmDeptVO.class, map.get("dept")))) {
                map.put("deptName", Convert.toList(SimpleHrmDeptVO.class, map.get("dept")).get(0).getDeptName());
                map.put("deptId", Convert.toList(SimpleHrmDeptVO.class, map.get("dept")).get(0).getDeptId());
            }
            if (map.get("org") != null && CollUtil.isNotEmpty(Convert.toList(SimpleHrmDeptVO.class, map.get("org")))) {
                map.put("orgName", Convert.toList(SimpleHrmDeptVO.class, map.get("org")).get(0).getDeptName());
                map.put("orgId", Convert.toList(SimpleHrmDeptVO.class, map.get("org")).get(0).getDeptId());
            }
            if (map.get("deptId") != null) {
                if (0 != (Long) map.get("deptId")) {
                    HrmDept hrmDept = hrmDeptService.getById((Long) map.get("deptId"));
                    if (0 == hrmDept.getParentId()) {
                        map.put("pid", "南昌市政公用集团有限公司");
                    } else {
                        HrmDept hrmDeptP = hrmDeptService.getById(hrmDept.getParentId());
                        map.put("pid", hrmDeptP.getName());
                    }
                } else {
                    map.put("pid", "南昌市政公用集团有限公司");
                }
            }
            if (map.get("sex") != null) {
                int sex = Integer.parseInt(map.get("sex").toString());
                map.put("sexCn", SexEnum.parseName(Optional.of(sex).orElse(-1)));
            }
        }
        return map;
    }

    @Override
    public BasePage<Map<String, Object>> queryPageList(QueryEmployeePageListBO employeePageListBO) {
        List<Long> birthdayEmpList = null;
        int six = 6;
        if (employeePageListBO.getToDoRemind() != null && employeePageListBO.getToDoRemind() == six) {
            birthdayEmpList = queryBirthdayEmp();
        }
        String sortField = StrUtil.isNotEmpty(employeePageListBO.getSortField()) ? StrUtil.toUnderlineCase(employeePageListBO.getSortField()) : null;
        employeePageListBO.setSortField(sortField);
//        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
        Collection<Long> employeeIds = employeeUtil.queryUserDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
        if (employeePageListBO.getDeptId() != null){
            //部门检索
            List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeePageListBO.getDeptId());
            employeePageListBO.setChildrenDeptIdList(deptIds);
            employeePageListBO.setDeptId(null);
        }

        Integer dataAuthType = adminService.queryDataType(UserUtil.getUserId(), MenuIdConstant.EMPLOYEE_MENU_ID).getData();
        // 当数据权限为本部门及下属部门时   可查看兼职人员
        if (DataAuthEnum.THIS_ORG_AND_SUBORDINATE.getValue().equals(dataAuthType)) {
//            Collection<Long> deptIds = new HashSet<>();;
            // 查询数据权限内的部门id  出错   单独写
//            deptIds = employeeUtil.queryDataAuthDeptId(dataAuthType, MenuIdConstant.EMPLOYEE_MENU_ID);
            EmployeeInfo employeeInfo = EmployeeHolder.getEmployeeInfo();
//            List<HrmEmployeeData> deptByEmpIdList = employeeDataService.lambdaQuery()
//                    .eq(HrmEmployeeData::getFieldName, "org")
//                    .eq(HrmEmployeeData::getEmployeeId, employeeInfo.getEmployeeId())
//                    .list();
//            if (CollectionUtils.isNotEmpty(deptByEmpIdList)) {
//                HrmEmployeeData data = deptByEmpIdList.stream().sorted(Comparator.comparing(HrmEmployeeData::getCreateTime).reversed()).findFirst().orElse(null);
//                if (data != null) {
//                    deptIds.add(Long.valueOf(data.getFieldValue()));
//                    deptIds.addAll(hrmDeptService.queryChildDeptId(Collections.singletonList(Long.valueOf(data.getFieldValue()))));
//                }
//            }
            if (employeeInfo.getOrgId() != null) {
                List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeeInfo.getOrgId());
                List<HrmEmployeeConcurrentPost> concurrentPostList = concurrentPostService.lambdaQuery().in(HrmEmployeeConcurrentPost::getDeptId, deptIds).ne(HrmEmployeeConcurrentPost::getEntryStatus, "离职").list();
                List<Long> concurrentPostEmployeeIdList = concurrentPostList.stream()
                        .map(HrmEmployeeConcurrentPost::getEmployeeId)
                        .filter(employeeId -> !employeeIds.contains(employeeId))
                        .collect(Collectors.toList());
                if (!concurrentPostEmployeeIdList.isEmpty()) {
                    employeeIds.addAll(concurrentPostEmployeeIdList);
                }
            }
        }

        BasePage<Map<String, Object>> page;
        //全文检索
        if (StrUtil.isNotEmpty(employeePageListBO.getEmployeeName()) && StrUtil.isNotEmpty(employeePageListBO.getEmployeeName().trim())) {
            page = this.fullTextSearch(employeePageListBO, employeeIds);
        }else {
            employeePageListBO.setEmployeeName(null);
            page = employeeMapper.queryPageList(employeePageListBO.parse(), employeePageListBO,  birthdayEmpList, employeeIds);
        }
//        BasePage<Map<String, Object>> page = employeeMapper.queryPageList(employeePageListBO.parse(), employeePageListBO,  birthdayEmpList, employeeIds);
        if (!StrUtil.isNotEmpty(employeePageListBO.getEmployeeName())) {
            page.getList().forEach(map -> {
                map.remove("deptName");
                map.remove("deptId");
                Long employeeId = Convert.toLong(map.get("employeeId"));
                List<JSONObject> fieldDatalist = employeeDataService.queryFiledListByEmployeeId(employeeId);
                for (JSONObject fieldData : fieldDatalist) {
                    if (StringUtils.isEmpty(fieldData.getString("fieldName"))) {
                        continue;
                    }
                    Object value = employeeFieldService
                            .convertValueByFormType(fieldData.getString("fieldValue"),
                                    FieldEnum.parse(Integer.valueOf(fieldData.getString("type"))));
                    map.put(StrUtil.toCamelCase(fieldData.getString("fieldName")), value);
                }
                String keyName = "joinCompanyTime";
                if (map.get(keyName) != null && ObjectUtil.notEqual(Convert.toInt(map.get("entryStatus")), EmployeeEntryStatusEnum.已离职.getValue())) {
                    LocalDateTime companyAgeStartTime = LocalDateTimeUtil.parse((String) map.get("joinCompanyTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    if (companyAgeStartTime != null){
                        long nowCompanyAge = LocalDateTimeUtil.between(companyAgeStartTime, LocalDateTime.now()).toDays() + 1;
                        if (LocalDateTimeUtil.toEpochMilli(companyAgeStartTime) > System.currentTimeMillis()) {
                            nowCompanyAge = 0;
                        }
                        map.put("companyAge", EmployeeUtil.computeCompanyAge((int) nowCompanyAge));
                    }
                }
                if (map.get("dept") != null && CollUtil.isNotEmpty(Convert.toList(SimpleHrmDeptVO.class, map.get("dept")))) {
                    map.put("deptName", Convert.toList(SimpleHrmDeptVO.class,map.get("dept")).get(0).getDeptName());
                    map.put("deptId", Convert.toList(SimpleHrmDeptVO.class,map.get("dept")).get(0).getDeptId());
                }
                if (map.get("org") != null && CollUtil.isNotEmpty(Convert.toList(SimpleHrmDeptVO.class, map.get("org")))) {
                    map.put("orgName", Convert.toList(SimpleHrmDeptVO.class,map.get("org")).get(0).getDeptName());
                    map.put("orgId", Convert.toList(SimpleHrmDeptVO.class,map.get("org")).get(0).getDeptId());
                }
                if (map.get("deptId") != null) {
                    if(0 != (Long) map.get("deptId")){
                        HrmDept hrmDept = hrmDeptService.getById((Long) map.get("deptId"));
                        if(0 == hrmDept.getParentId()){
                            map.put("pid", "南昌市政公用集团有限公司");
                        }else{
                            HrmDept hrmDeptP = hrmDeptService.getById(hrmDept.getParentId());
                            map.put("pid", hrmDeptP.getName());
                        }
                    }else{
                        map.put("pid", "南昌市政公用集团有限公司");
                    }
                }
                if (map.get("sex") != null){
                    int sex = Integer.parseInt(map.get("sex").toString());
                    map.put("sexCn", SexEnum.parseName(Optional.of(sex).orElse(-1)));
                }
            });
        }
        return page;
    }

    @Override
    public BasePage<Map<String, Object>> fullTextSearch(QueryEmployeePageListBO employeePageListBO,Collection<Long> employeeIds) {
        BasePage<Map<String, Object>> mapBasePage = new BasePage<>();
        mapBasePage.setCurrent(employeePageListBO.getPage());
        mapBasePage.setSize(employeePageListBO.getLimit());
        if (employeeIds.isEmpty()){
            return mapBasePage;
        }
        // 搜索框条件
        List<String> keyList = Arrays.stream(employeePageListBO.getEmployeeName().split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
        StringBuilder keyStr = new StringBuilder();
        // 函数得分条件
        List<FunctionScore> functions = new ArrayList<>();
        for (int i = 0; i < keyList.size(); i++) {
            String key = keyList.get(i);
            // 正则表达式，匹配所有非字母、数字、汉字的字符
            String regex = "[^a-zA-Z0-9\u4e00-\u9fa5]";
            if(i == 0){
                if (key.matches(regex)){
                    keyStr.append("\"").append(key).append("\"");
                }else {
                    keyStr.append("*").append(key).append("*");
                }
            }else {
                if (key.matches(regex)){
                    keyStr.append("OR \"").append(key).append("\"");
                }else {
                    keyStr.append(" OR *").append(key).append("*");
                }
            }

            functions.add(FunctionScore.of(f -> f
                    .filter(f1 -> f1.wildcard(w -> w.field("employeeName.keyword").value("*" + key + "*")))
                    .weight(2.0)
            ));
            functions.add(FunctionScore.of(f -> f
                    .filter(f1 -> f1.term(w -> w.field("employeeName.keyword").value(key)))
                    .weight(2.0)
            ));
        }
        String finalKeyStr = keyStr.toString();
        //组合查询
        SearchRequest searchRequest;
        //构建查询条件
        Query query = new Query.Builder().functionScore(
                fs -> fs.query(q -> q.bool(builder -> {
                            List<Query> queries = new ArrayList<>();
                            //员工编号
                            List<FieldValue> empIds = employeeIds.stream().map(FieldValue::of).collect(Collectors.toList());
                            queries.add(new Query.Builder().terms(terms -> terms.field("employeeId").terms(v -> v.value(empIds))).build());
                            //全局索引
                            if (StrUtil.isNotEmpty(employeePageListBO.getEmployeeName())) {
                                queries.add(new Query.Builder()
                                        .queryString(qs -> qs.fields("*")
                                                .analyzer("keyword")
                                                .query(finalKeyStr)).build());
                            }
                            //手机号码
                            if (StrUtil.isNotEmpty(employeePageListBO.getMobile())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("mobile").value("*" + employeePageListBO.getMobile() + "*")).build());
                            }
                            //性别
                            if (employeePageListBO.getSex() != null) {
                                queries.add(new Query.Builder().term(term -> term.field("sex").value(employeePageListBO.getSex())).build());
                            }
                            //工作地点
                            if (StrUtil.isNotEmpty(employeePageListBO.getWorkAddress())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("workAddress.keyword").value("*" + employeePageListBO.getWorkAddress() + "*")).build());
                            }
                            //用工形式
                            if (StrUtil.isNotEmpty(employeePageListBO.getWorkType())) {
                                queries.add(new Query.Builder().term(term -> term.field("workForms.keyword").value(employeePageListBO.getWorkType())).build());
                            }
                            //在岗状态
                            if (StrUtil.isNotEmpty(employeePageListBO.getEntryStatus())) {
                                queries.add(new Query.Builder().term(term -> term.field("postStatus.keyword").value(employeePageListBO.getEntryStatus())).build());
                            }
                            //入职日期
                            if (employeePageListBO.getEntryTime() != null && !employeePageListBO.getEntryTime().isEmpty()) {
                                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                LocalDate startDate = employeePageListBO.getEntryTime().get(0);
                                LocalDate endDate = employeePageListBO.getEntryTime().get(1);
                                String startDateStr = startDate.format(formatter);
                                String endDateStr = endDate.format(formatter);
                                queries.add(new Query.Builder().range(range -> range.field("entryTime").gte(JsonData.of(startDateStr)).lte(JsonData.of(endDateStr)).format("yyyy-MM-dd")).build());
                            }
                            //职务
                            if (StrUtil.isNotEmpty(employeePageListBO.getJobTitle())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("jobTitle.keyword").value("*" + employeePageListBO.getJobTitle() + "*")).build());
                            }
                            //身份证号
                            if (StrUtil.isNotEmpty(employeePageListBO.getIdNumber())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("idNumber.keyword").value("*" + employeePageListBO.getIdNumber() + "*")).build());
                            }
                            //转正日期
                            if (employeePageListBO.getBecomeTime() != null && !employeePageListBO.getBecomeTime().isEmpty()) {
                                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                LocalDate startDate = employeePageListBO.getBecomeTime().get(0);
                                LocalDate endDate = employeePageListBO.getBecomeTime().get(1);
                                String startDateStr = startDate.format(formatter);
                                String endDateStr = endDate.format(formatter);
                                queries.add(new Query.Builder().range(range -> range.field("becomeTime").gte(JsonData.of(startDateStr)).lte(JsonData.of(endDateStr)).format("yyyy-MM-dd")).build());
                            }
                            //部门
                            if (employeePageListBO.getChildrenDeptIdList() != null) {
                                List<FieldValue> deptIds = employeePageListBO.getChildrenDeptIdList().stream().map(FieldValue::of).collect(Collectors.toList());
                                queries.add(new Query.Builder().terms(terms -> terms.field("deptId").terms(v -> v.value(deptIds))).build());
                            }
                            //部门名称
                            if (StrUtil.isNotEmpty(employeePageListBO.getDeptName())) {
                                queries.add(new Query.Builder().term(term -> term.field("deptName.keyword").value(employeePageListBO.getDeptName())).build());
                            }
                            //年龄
                            if (employeePageListBO.getAge() != null && !employeePageListBO.getAge().isEmpty()) {
                                List<String> age = employeePageListBO.getAge();
                                if (StrUtil.isNotEmpty(age.get(0)) && StrUtil.isNotEmpty(age.get(1))) {
                                    queries.add(new Query.Builder().range(range -> range.field("age").gte(JsonData.of(employeePageListBO.getAge().get(0))).lte(JsonData.of(employeePageListBO.getAge().get(1)))).build());
                                } else if (StrUtil.isNotEmpty(age.get(0))) {
                                    queries.add(new Query.Builder().range(range -> range.field("age").gte(JsonData.of(employeePageListBO.getAge().get(0)))).build());
                                } else if (StrUtil.isNotEmpty(age.get(1))) {
                                    queries.add(new Query.Builder().range(range -> range.field("age").lte(JsonData.of(employeePageListBO.getAge().get(1)))).build());
                                }
                            }
                            //外语水平
                            if (StrUtil.isNotEmpty(employeePageListBO.getLanguageLevel())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("languageLevelName.keyword").value("*" + employeePageListBO.getLanguageLevel() + "*")).build());
                            }
                            //专业技术资格
                            if (StrUtil.isNotEmpty(employeePageListBO.getTechnicalName())) {
                                queries.add(new Query.Builder().term(term -> term.field("technicalList.technicalName.keyword").value(employeePageListBO.getTechnicalName())).build());
                            }
                            //最高学历
                            if (employeePageListBO.getHighestEducation() != null) {
                                queries.add(new Query.Builder().term(term -> term.field("highestEducation").value(employeePageListBO.getHighestEducation())).build());
                            }
                            //职位层级
                            if (StrUtil.isNotEmpty(employeePageListBO.getPostLevel())) {
                                queries.add(new Query.Builder().term(term -> term.field("jobLevel.keyword").value(employeePageListBO.getPostLevel())).build());
                            }
                            //职称级别
                            if (StrUtil.isNotEmpty(employeePageListBO.getTechnicalLevel())) {
                                queries.add(new Query.Builder().term(term -> term.field("technicalList.technicalLevel.keyword").value(employeePageListBO.getTechnicalLevel())).build());
                            }
                            //专技等级
                            if (StrUtil.isNotEmpty(employeePageListBO.getSpecialWorkerLevel())) {
                                queries.add(new Query.Builder().term(term -> term.field("specialWorkerList.specialWorkerLevel.keyword").value(employeePageListBO.getSpecialWorkerLevel())).build());
                            }
                            //专业
                            if (StrUtil.isNotEmpty(employeePageListBO.getMajor())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("educationExperienceList.major.keyword").value("*" + employeePageListBO.getMajor() + "*")).build());
                            }
                            //学校名称
                            if (StrUtil.isNotEmpty(employeePageListBO.getSchoolName())) {
                                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("educationExperienceList.graduateSchool.keyword").value("*" + employeePageListBO.getSchoolName() + "*")).build());
                            }
                            //教育形式
                            if (employeePageListBO.getTeachingMethods() != null) {
                                queries.add(new Query.Builder().term(term -> term.field("educationExperienceList.teachingMethods").value(employeePageListBO.getTeachingMethods())).build());
                            }
                            return builder.must(queries);
                        }))
//                        .functions(
//                                new Function<FunctionScore.Builder, ObjectBuilder<FunctionScore>>() {
//                                    @Override
//                                    public ObjectBuilder<FunctionScore> apply(FunctionScore.Builder builder) {
//
//                                        builder.filter(filter -> filter.queryString(qs -> qs.query(finalKeyStr).fields(Lists.newArrayList("employeeName"))))
//                                                .weight(5.0);
////                                        for (int i = 0; i < keyList.size(); i++) {
////                                            String key = keyList.get(i);
////                                            builder.filter(filter -> filter.term(t -> t.field("employeeName.keyword").value(key)))
////                                                    .weight(10.0);
////                                        }
//                                        return builder;
//                                    }
//                                }
////                                ft -> ft
////                                        .filter(filter -> filter.queryString(qs -> qs.query(finalKeyStr).fields(Lists.newArrayList("employeeName"))))
////                                        .weight(3.0)
////                                        .filter(filter -> filter.term(t -> t.field("employeeName.keyword").value(finalKeyStr)))
////                                        .weight(5.0)
//                        )
                        .functions(functions)
                        .boostMode(FunctionBoostMode.Sum)
                        .scoreMode(FunctionScoreMode.Sum)
                        .maxBoost(100.0)
        ).build();

        /*
        Query query = new Query.Builder().bool(builder -> {
            List<Query> queries = new ArrayList<>();
            //员工编号
            List<FieldValue> empIds = employeeIds.stream().map(FieldValue::of).collect(Collectors.toList());
            queries.add(new Query.Builder().terms(terms -> terms.field("employeeId").terms(v -> v.value(empIds))).build());
            //全局索引
            if (StrUtil.isNotEmpty(employeePageListBO.getEmployeeName())){
//                best_fields：最高评分,most_fields：多字段 综合评分
//                queries.add(new Query.Builder()
//                        .multiMatch(multiMatch -> multiMatch.fields("*")
//                                .query(employeePageListBO.getEmployeeName())
//                                .type(TextQueryType.MostFields)
//                                .analyzer("ik_max_word")).build());

                List<String> keyList = Arrays.stream(employeePageListBO.getEmployeeName().split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());

//                Query shouldQuery = new Query.Builder().bool(s -> {
//                    List<Query> shouldQueries = new ArrayList<>();
//                    for (int i = 0; i < keyList.size(); i++) {
//                        String key = keyList.get(i);
//                        if (StrUtil.isNotEmpty(key)){
//                            shouldQueries.add(new Query.Builder()
//                                    .queryString(qs -> qs.fields("*")
//                                            .analyzer("keyword")
//                                            .query("*" + key + "*")).build());
//                        }
//                    }
//                    return s.should(shouldQueries);
//                }).build();
//                queries.add(shouldQuery);
                StringBuilder keyStr = new StringBuilder();
                for (int i = 0; i < keyList.size(); i++) {
                    String key = keyList.get(i);
                    // 正则表达式，匹配所有非字母、数字、汉字的字符
                    String regex = "[^a-zA-Z0-9\u4e00-\u9fa5]";
                    if(i == 0){
                        if (key.matches(regex)){
                            keyStr.append("\"").append(key).append("\"");
                        }else {
                            keyStr.append("*").append(key).append("*");
                        }
                    }else {
                        if (key.matches(regex)){
                            keyStr.append("OR \"").append(key).append("\"");
                        }else {
                            keyStr.append(" OR *").append(key).append("*");
                        }
                    }
                }
                String finalKeyStr = keyStr.toString();
                queries.add(new Query.Builder()
                        .queryString(qs -> qs.fields("*")
                                .analyzer("keyword")
                                .query(finalKeyStr)).build());
            }
            //手机号码
            if (StrUtil.isNotEmpty(employeePageListBO.getMobile())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("mobile").value("*" + employeePageListBO.getMobile() + "*")).build());
            }
            //性别
            if (employeePageListBO.getSex() != null){
                queries.add(new Query.Builder().term(term -> term.field("sex").value(employeePageListBO.getSex())).build());
            }
            //工作地点
            if (StrUtil.isNotEmpty(employeePageListBO.getWorkAddress())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("workAddress.keyword").value("*" + employeePageListBO.getWorkAddress() + "*")).build());
            }
            //用工形式
            if (StrUtil.isNotEmpty(employeePageListBO.getWorkType())){
                queries.add(new Query.Builder().term(term -> term.field("workForms.keyword").value(employeePageListBO.getWorkType())).build());
            }
            //在岗状态
            if (StrUtil.isNotEmpty(employeePageListBO.getEntryStatus())){
                queries.add(new Query.Builder().term(term -> term.field("postStatus.keyword").value(employeePageListBO.getEntryStatus())).build());
            }
            //入职日期
            if (employeePageListBO.getEntryTime() != null && !employeePageListBO.getEntryTime().isEmpty()){
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDate = employeePageListBO.getEntryTime().get(0);
                LocalDate endDate = employeePageListBO.getEntryTime().get(1);
                String startDateStr = startDate.format(formatter);
                String endDateStr = endDate.format(formatter);
                queries.add(new Query.Builder().range(range -> range.field("entryTime").gte(JsonData.of(startDateStr)).lte(JsonData.of(endDateStr)).format("yyyy-MM-dd")).build());
            }
            //职务
            if (StrUtil.isNotEmpty(employeePageListBO.getJobTitle())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("jobTitle.keyword").value("*" + employeePageListBO.getJobTitle() + "*")).build());
            }
            //身份证号
            if (StrUtil.isNotEmpty(employeePageListBO.getIdNumber())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("idNumber.keyword").value("*" + employeePageListBO.getIdNumber() + "*")).build());
            }
            //转正日期
            if (employeePageListBO.getBecomeTime() != null && !employeePageListBO.getBecomeTime().isEmpty()){
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDate = employeePageListBO.getBecomeTime().get(0);
                LocalDate endDate = employeePageListBO.getBecomeTime().get(1);
                String startDateStr = startDate.format(formatter);
                String endDateStr = endDate.format(formatter);
                queries.add(new Query.Builder().range(range -> range.field("becomeTime").gte(JsonData.of(startDateStr)).lte(JsonData.of(endDateStr)).format("yyyy-MM-dd")).build());
            }
            //部门
            if (employeePageListBO.getChildrenDeptIdList() != null){
//                queries.add(new Query.Builder().term(term -> term.field("deptId").values(employeePageListBO.getChildrenDeptIdList())).build());
                List<FieldValue> deptIds = employeePageListBO.getChildrenDeptIdList().stream().map(FieldValue::of).collect(Collectors.toList());
                queries.add(new Query.Builder().terms(terms -> terms.field("deptId").terms(v -> v.value(deptIds))).build());
            }
            //部门名称
            if (StrUtil.isNotEmpty(employeePageListBO.getDeptName())){
                queries.add(new Query.Builder().term(term -> term.field("deptName.keyword").value(employeePageListBO.getDeptName())).build());
            }
            //年龄
            if (employeePageListBO.getAge() != null && !employeePageListBO.getAge().isEmpty()){
                List<String> age = employeePageListBO.getAge();
                if (StrUtil.isNotEmpty(age.get(0)) && StrUtil.isNotEmpty(age.get(1))){
                    queries.add(new Query.Builder().range(range -> range.field("age").gte(JsonData.of(employeePageListBO.getAge().get(0))).lte(JsonData.of(employeePageListBO.getAge().get(1)))).build());
                }else if (StrUtil.isNotEmpty(age.get(0))){
                    queries.add(new Query.Builder().range(range -> range.field("age").gte(JsonData.of(employeePageListBO.getAge().get(0)))).build());
                }else if (StrUtil.isNotEmpty(age.get(1))){
                    queries.add(new Query.Builder().range(range -> range.field("age").lte(JsonData.of(employeePageListBO.getAge().get(1)))).build());
                }
            }
            //外语水平
            if (StrUtil.isNotEmpty(employeePageListBO.getLanguageLevel())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("languageLevelName.keyword").value("*" + employeePageListBO.getLanguageLevel() + "*")).build());
            }
            //专业技术资格
            if (StrUtil.isNotEmpty(employeePageListBO.getTechnicalName())){
                queries.add(new Query.Builder().term(term -> term.field("technicalList.technicalName.keyword").value(employeePageListBO.getTechnicalName())).build());
            }
            //最高学历
            if (employeePageListBO.getHighestEducation() != null){
                queries.add(new Query.Builder().term(term -> term.field("highestEducation").value(employeePageListBO.getHighestEducation())).build());
            }
            //职位层级
            if (StrUtil.isNotEmpty(employeePageListBO.getPostLevel())){
                queries.add(new Query.Builder().term(term -> term.field("jobLevel.keyword").value(employeePageListBO.getPostLevel())).build());
            }
            //职称级别
            if (StrUtil.isNotEmpty(employeePageListBO.getTechnicalLevel())){
                queries.add(new Query.Builder().term(term -> term.field("technicalList.technicalLevel.keyword").value(employeePageListBO.getTechnicalLevel())).build());
            }
            //专技等级
            if (StrUtil.isNotEmpty(employeePageListBO.getSpecialWorkerLevel())){
                queries.add(new Query.Builder().term(term -> term.field("specialWorkerList.specialWorkerLevel.keyword").value(employeePageListBO.getSpecialWorkerLevel())).build());
            }
            //专业
            if (StrUtil.isNotEmpty(employeePageListBO.getMajor())){
                queries.add(new Query.Builder().wildcard(wildcard -> wildcard.field("educationExperienceList.major.keyword").value("*" + employeePageListBO.getMajor() + "*")).build());
            }
            return builder.must(queries);
        }).build();

        */
        SearchRequest.Builder requestBuilder = new SearchRequest.Builder().trackTotalHits(new TrackHits.Builder().enabled(true).build()).query(query);

        Integer pageType = employeePageListBO.getPageType();
        if (pageType == 1){
//            .index(employeeIds.stream().map(Object::toString).collect(Collectors.toList()))
            requestBuilder.from((int) ((employeePageListBO.getPage() - 1) * employeePageListBO.getLimit())).size(employeePageListBO.getLimit().intValue());
        }
        if(StrUtil.isNotEmpty(employeePageListBO.getSortField())){
            requestBuilder.sort(s -> s.field(f -> f.field(StrUtil.toCamelCase(employeePageListBO.getSortField())).order(employeePageListBO.getOrder() == 1 ? SortOrder.Asc : SortOrder.Desc)));
        }
        if (employeePageListBO.getIsHighlight()){
            // 设置高亮
//        requestBuilder.highlight(h -> h.fields("*", f -> f).preTags("<font color='red'>").postTags("</font>"));
            requestBuilder.highlight(h -> h.fields("*", f -> f).preTags("<!sFrd2D4%>").postTags("<!sFrd2D4%>"));
        }
        searchRequest = requestBuilder.build();

        try {
            final SearchResponse<JSONObject> response = EsUtil.getClient()
                    .search(searchRequest, JSONObject.class);
            //总条数
            long value = response.hits().total().value();
            mapBasePage.setTotal(value);
            //数据
            List<Hit<JSONObject>> hits = response.hits().hits();
            if (hits != null && !hits.isEmpty()) {
                List<Map<String, Object>> list = new ArrayList<>();
                for (Hit<JSONObject> hit : hits) {
                    JSONObject source = hit.source();
                    Map<String, List<String>> highlight = Optional.ofNullable(hit.highlight()).orElse(new HashMap<>());
                    Map<String, Object> map = new HashMap<>();
                    for (String key : source.keySet()) {
                        if (!employeePageListBO.getIsOtherInfo() && source.get(key) instanceof List){
                            continue;
                        }
                        //高亮
                        if (employeePageListBO.getIsHighlight() && highlight.get(key) != null && !highlight.get(key).isEmpty()) {
                            String s = highlight.get(key).get(0);
                            String replace = s.replace("<!sFrd2D4%>", "");
                            for (String string : keyList) {
                                replace = replace.replaceAll(string, "<font color='red'>" + string + "</font>");
                            }
                            map.put(key, replace);
                        } else if (employeePageListBO.getIsHighlight() && highlight.get(key + ".keyword") != null && !highlight.get(key + ".keyword").isEmpty()) {
                            String s = highlight.get(key + ".keyword").get(0);
                            String replace = s.replace("<!sFrd2D4%>", "");
                            for (String string : keyList) {
                                replace = replace.replaceAll(string, "<font color='red'>" + string + "</font>");
                            }
                            map.put(key, replace);
                        }else {
                            map.put(key, source.get(key));
                        }
                    }
                    list.add(map);
                }
                mapBasePage.setList(list);
            }
        } catch (IOException e) {
            log.error("es数据查询失败", e);
            throw new CrmException(SystemCodeEnum.SYSTEM_SERVER_ERROR);
        }
        return mapBasePage;
    }


    public Map<String, HrmEmployeeField> getEmployeeFieldMap() {
        List<HrmEmployeeField> hrmEmployeeFields = employeeFieldService.lambdaQuery().select(HrmEmployeeField::getName, HrmEmployeeField::getFieldName,
                        HrmEmployeeField::getType, HrmEmployeeField::getComponentType)
                .eq(HrmEmployeeField::getIsHeadField, 1).eq(HrmEmployeeField::getIsFixed, 0).eq(HrmEmployeeField::getIsHidden, 0)
                .list();
        Map<String, HrmEmployeeField> employeeFieldMap = new HashMap<>();
        for (HrmEmployeeField employeeField : hrmEmployeeFields) {
            employeeFieldMap.put(employeeField.getFieldName(), employeeField);
            if (employeeField.getComponentType().equals(ComponentType.ADMIN_USER.getValue()) && !employeeFieldMap.containsKey("dept")) {
                employeeFieldMap.put("dept", null);
            } else if (employeeField.getType().equals(ComponentType.ADMIN_DEPT.getValue()) && !employeeFieldMap.containsKey("user")) {
                employeeFieldMap.put("user", null);
            }
        }
        return employeeFieldMap;
    }

    @Override
    public List<SimpleHrmEmployeeVO> querySimpleEmployeeList(Collection<Long> employeeIds) {
        if (CollUtil.isEmpty(employeeIds)) {
            return new ArrayList<>();
        }
        return lambdaQuery().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName)
                .in(HrmEmployee::getEmployeeId, employeeIds).eq(HrmEmployee::getIsDel, 0).list()
                .stream().map(employee -> {
                    SimpleHrmEmployeeVO simpleHrmEmployeeVO = new SimpleHrmEmployeeVO();
                    simpleHrmEmployeeVO.setEmployeeId(employee.getEmployeeId());
                    simpleHrmEmployeeVO.setEmployeeName(employee.getEmployeeName());
                    return simpleHrmEmployeeVO;
                }).collect(Collectors.toList());
    }

    @Override
    public Map<Integer, Long> queryEmployeeStatusNum(QueryEmployeePageListBO employeePageListBO) {
        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
        /*
        List<HrmEmployee> list;
        List<HrmEmployee> listSex;
        if (employeeIds != null && employeeIds.size() == 0) {
            list = new ArrayList<>();
            listSex = new ArrayList<>();
        } else {
            if (employeePageListBO.getDeptId() != null){
                //部门检索
                List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeePageListBO.getDeptId());
                employeePageListBO.setChildrenDeptIdList(deptIds);
                employeePageListBO.setDeptId(null);
            }
            list = employeeMapper.queryListStatus(employeePageListBO, employeeIds);
            listSex = employeeMapper.queryListSex(employeePageListBO, employeeIds);
        }
        //查询在职状态人数
        TreeMap<Integer, Long> collect = list
                .stream().collect(Collectors.groupingBy(HrmEmployee::getStatus, TreeMap::new, Collectors.counting()));
        for (EmployeeStatusEnum value : EmployeeStatusEnum.values()) {
            if (!collect.containsKey(value.getValue())) {
                collect.put(value.getValue(), 0L);
            }
        }
        TreeMap<Integer, Long> mapUser = listSex
                .stream().collect(Collectors.groupingBy(s->Optional.ofNullable(s.getSex()).orElse(1), TreeMap::new, Collectors.counting()));
        if(mapUser != null){
            long fCnt = 0L;
            long mCnt = 0L;
            if(mapUser.get(1) != null){
                fCnt = Long.valueOf(mapUser.get(1));
            }
            if(mapUser.get(2) != null){
                mCnt = Long.valueOf(mapUser.get(2));
            }
            collect.put(21, fCnt + mCnt);
            collect.put(22, fCnt);
            collect.put(23, mCnt);
        }else{
            collect.put(21, 0L);
            collect.put(22, 0L);
            collect.put(23, 0L);
        }

        //在职
        collect.put(11, (long) list.size());
        if (employeeIds != null && employeeIds.size() == 0) {
            //全职(正式+试用)
            collect.put(12, 0L);
            //待入职
            collect.put(13, 0L);
            //待离职
            collect.put(14, 0L);
            //已离职
            collect.put(15, 0L);
        } else {
            //全职(正式+试用)
            collect.put(12, employeeMapper.queryCountQz(employeePageListBO, employeeIds));
            //待入职
            collect.put(13, employeeMapper.queryCountDrz(employeePageListBO, employeeIds, EmployeeEntryStatus.TO_IN.getValue()));
            //待离职
            collect.put(14, employeeMapper.queryCountDrz(employeePageListBO, employeeIds, EmployeeEntryStatus.TO_LEAVE.getValue()));
            //已离职
            collect.put(15, employeeMapper.queryCountDrz(employeePageListBO, employeeIds, EmployeeEntryStatus.ALREADY_LEAVE.getValue()));
        }
         */
        if (employeeIds == null || employeeIds.isEmpty()) {
            return new HashMap<>();
        }
        if (employeePageListBO.getDeptId() != null){
            //部门检索
            List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeePageListBO.getDeptId());
            employeePageListBO.setChildrenDeptIdList(deptIds);
            employeePageListBO.setDeptId(null);
        }
        return employeeMapper.getEmployeeStatusTotal(employeePageListBO, employeeIds);
    }
//    @Override
//    public Map<Integer, Long> queryEmployeeStatusNum() {
//        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
//
//        List<HrmEmployee> list;
//        List<HrmEmployee> listSex;
//        if (employeeIds != null && employeeIds.size() == 0) {
//            list = new ArrayList<>();
//            listSex = new ArrayList<>();
//        } else {
//            list = lambdaQuery().select(HrmEmployee::getStatus)
//                    .in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.IN.getValue(), EmployeeEntryStatus.TO_LEAVE.getValue())
//                    .in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds)
//                    .eq(HrmEmployee::getIsDel, 0)
//                    .list();
//
//            listSex = lambdaQuery().select(HrmEmployee::getSex)
//                    .in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.IN.getValue(), EmployeeEntryStatus.TO_LEAVE.getValue())
//                    .in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds)
//                    .eq(HrmEmployee::getIsDel, 0)
//                    .list();
//        }
//
//        //查询在职状态人数
//        TreeMap<Integer, Long> collect = list
//                .stream().collect(Collectors.groupingBy(HrmEmployee::getStatus, TreeMap::new, Collectors.counting()));
//        for (EmployeeStatusEnum value : EmployeeStatusEnum.values()) {
//            if (!collect.containsKey(value.getValue())) {
//                collect.put(value.getValue(), 0L);
//            }
//        }
//
//        TreeMap<Integer, Long> mapUser = listSex
//                .stream().collect(Collectors.groupingBy(s->Optional.ofNullable(s.getSex()).orElse(1), TreeMap::new, Collectors.counting()));
//        if(mapUser != null){
//            long fCnt = 0L;
//            long mCnt = 0L;
//            if(mapUser.get(1) != null){
//                fCnt = Long.valueOf(mapUser.get(1));
//            }
//            if(mapUser.get(2) != null){
//                mCnt = Long.valueOf(mapUser.get(2));
//            }
//            collect.put(21, fCnt + mCnt);
//            collect.put(22, fCnt);
//            collect.put(23, mCnt);
//        }else{
//            collect.put(21, 0L);
//            collect.put(22, 0L);
//            collect.put(23, 0L);
//        }
//
//        //在职
//        collect.put(11, (long) list.size());
//        if (employeeIds != null && employeeIds.size() == 0) {
//            //全职(正式+试用)
//            collect.put(12, 0L);
//            //待入职
//            collect.put(13, 0L);
//            //待离职
//            collect.put(14, 0L);
//            //已离职
//            collect.put(15, 0L);
//        } else {
//            //全职(正式+试用)
//            Long fullTimeCount = lambdaQuery().in(HrmEmployee::getStatus, EmployeeStatusEnum.OFFICIAL.getValue(), EmployeeStatusEnum.TRY_OUT.getValue())
//                    .in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds)
//                    .eq(HrmEmployee::getIsDel, 0)
//                    .in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.IN.getValue(), EmployeeEntryStatus.TO_LEAVE.getValue()).count();
//            collect.put(12, Long.valueOf(fullTimeCount));
//            //待入职
//            collect.put(13, Long.valueOf(lambdaQuery().in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds).in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.TO_IN.getValue()).eq(HrmEmployee::getIsDel, 0).count()));
//            //待离职
//            collect.put(14, Long.valueOf(lambdaQuery().in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds).in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.TO_LEAVE.getValue()).eq(HrmEmployee::getIsDel, 0).count()));
//            //已离职
//            collect.put(15, Long.valueOf(lambdaQuery().in(employeeIds != null, HrmEmployee::getEmployeeId, employeeIds).in(HrmEmployee::getEntryStatus, EmployeeEntryStatus.ALREADY_LEAVE.getValue()).eq(HrmEmployee::getIsDel, 0).count()));
//        }
//        return collect;
//    }

    @Override
    public OperationLog againOnboarding(AddEmployeeFieldManageBO addEmployeeFieldManageBO) {
        //删除离职信息
        quitInfoService.lambdaUpdate().eq(HrmEmployeeQuitInfo::getEmployeeId, addEmployeeFieldManageBO.getEmployeeId())
                .remove();
        // 员工个人信息自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeFieldList = addEmployeeFieldManageBO.getEmployeeFieldList();
        // 员工岗位自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> postFieldList = addEmployeeFieldManageBO.getPostFieldList();
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeDataList = Stream.concat(employeeFieldList.stream(), postFieldList.stream()).collect(Collectors.toList());
        Map<FiledIsFixedEnum, List<AddEmployeeFieldManageBO.EmployeeFieldBO>> isFixedMap = getIsFixedMap(employeeDataList);
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), employeeData.getFieldValue()));


        HrmEmployee hrmEmployee = getById(addEmployeeFieldManageBO.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(hrmEmployee.getEmployeeId(), hrmEmployee.getEmployeeName());
        operationLog.setOperationInfo("为" + hrmEmployee.getEmployeeName() + "办理再入职");
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        employee.setEmployeeId(addEmployeeFieldManageBO.getEmployeeId());
        employee.setEntryStatus(EmployeeEntryStatusEnum.再入职.getValue());
        if (null == employee.getCompanyAgeStartTime()) {
            employee.setCompanyAgeStartTime(employee.getEntryTime());
        }
        transferEmployee(employee);
        updateById(employee);

        // 获取修改签前的岗位信息
        List<HrmEmployeeData> hrmEmployeeDataList = hrmEmployeeDataMapper.queryEmployeeFiledListByEmployeeId(employee.getEmployeeId());
        Map<String, HrmEmployeeData> hrmEmployeeDataMap = new HashMap<>();
        if (hrmEmployeeDataList != null && !hrmEmployeeDataList.isEmpty()) {
            hrmEmployeeDataMap = hrmEmployeeDataList.stream().collect(Collectors.toMap(HrmEmployeeData::getFieldName, Function.identity(), (old, newData) -> newData));
        }

        List<HrmEmployeeData> hrmEmployeeData = isFixedMap.get(FiledIsFixedEnum.NO_FIXED).stream()
                .map(field -> {
                    Object value = field.getFieldValue();
                    if (value == null) {
                        value = "";
                    }
                    field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                    return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                }).collect(Collectors.toList());
        if (!hrmEmployeeData.isEmpty()) {
            List<HrmEmployeeData> personalData = hrmEmployeeData.stream().filter(employeeData -> employeeData.getLabelGroup().equals(LabelGroupEnum.PERSONAL.getValue())).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(personalData, LabelGroupEnum.PERSONAL, employee.getEmployeeId());
            List<HrmEmployeeData> postData = hrmEmployeeData.stream().filter(employeeData -> employeeData.getLabelGroup().equals(LabelGroupEnum.POST.getValue())).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(postData, LabelGroupEnum.POST, employee.getEmployeeId());
        }
        boolean exists = employeeFieldService.query().eq("field_name", "flied_kwbova").eq("label_group", LabelGroupEnum.COMMUNICATION.getValue()).eq("type", FieldTypeEnum.MOBILE.getValue()).exists();
        if (exists) {
            //若是存在自定义手机号码字段，则进行更新
            JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employee.getEmployeeId());
            List<InformationFieldVO> communicationInformation = transferInformation(employeeModel, LabelGroupEnum.COMMUNICATION, fieldValueList);
            List<InformationFieldVO> informationFieldVOS = communicationInformation.stream().collect(Collectors.groupingBy(employeeData -> FiledIsFixedEnum.parse(employeeData.getIsFixed()))).get(FiledIsFixedEnum.NO_FIXED);
            String fliedKwbova = "flied_kwbova";
            List<HrmEmployeeData> hrmEmployeeInformationData = informationFieldVOS.stream()
                    .map(field -> {
                        if (fliedKwbova.equals(field.getFieldName()) && field.getType().equals(FieldTypeEnum.MOBILE.getValue())) {
                            field.setFieldValue(employee.getMobile());
                            field.setFieldValueDesc(employee.getMobile());
                        }
                        Object value = field.getFieldValue();
                        if (value == null) {
                            value = "";
                        }
                        field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                        return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                    }).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(hrmEmployeeInformationData, LabelGroupEnum.COMMUNICATION, employee.getEmployeeId());
        }

        // 保存记录
        StringBuffer sb = new StringBuffer();
        sb.append("员工[").append(hrmEmployee.getEmployeeName()).append("]办理再入职。");

        String companyAgeStartTime = "";
        String joinCompanyTime = "";
        for (int i = 0; i < postFieldList.size(); i++) {
            AddEmployeeFieldManageBO.EmployeeFieldBO employeeFieldBO = postFieldList.get(i);
            if ("join_company_time".equals(employeeFieldBO.getFieldName()) && employeeFieldBO.getFieldValue() != null) {
                joinCompanyTime = employeeFieldBO.getFieldValue().toString();
            }
            if ("company_age_start_time".equals(employeeFieldBO.getFieldName()) && employeeFieldBO.getFieldValue() != null) {
                companyAgeStartTime = employeeFieldBO.getFieldValue().toString();
            }
        }
        if (hrmEmployeeDataMap.containsKey("join_company_time")) {
            sb.append("原入集团时间：").append(hrmEmployeeDataMap.get("join_company_time").getFieldValue()).append(" 调整为：").append(joinCompanyTime).append("。");
        } else {
            sb.append("原入集团时间：空 ").append(" 调整为：").append(joinCompanyTime).append("。");
        }
        LocalDate startTime = hrmEmployee.getCompanyAgeStartTime();
        String timeStr = null;
        if (startTime != null) {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            timeStr = startTime.format(df);
        }
        sb.append("原入司时间：").append(timeStr).append(" 调整为：").append(companyAgeStartTime).append("。");

        employeeActionRecordService.addAgainOnboardingRecord(sb.toString(), addEmployeeFieldManageBO.getEmployeeId());

        abnormalChangeRecordService.addAbnormalChangeRecord(employee.getEmployeeId(), AbnormalChangeType.NEW_ENTRY, LocalDateTime.now());
        return operationLog;
    }

    @Override
    public EmployeeInfo queryEmployeeInfoByMobile(String mobile) {
        return employeeMapper.queryEmployeeInfoByMobile(mobile);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog confirmEntry(AddEmployeeFieldManageBO addEmployeeFieldManageBO) {
        // 员工个人信息自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeFieldList = addEmployeeFieldManageBO.getEmployeeFieldList();
        // 员工岗位自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> postFieldList = addEmployeeFieldManageBO.getPostFieldList();
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeDataList = Stream.concat(employeeFieldList.stream(), postFieldList.stream()).collect(Collectors.toList());
        Map<FiledIsFixedEnum, List<AddEmployeeFieldManageBO.EmployeeFieldBO>> isFixedMap = getIsFixedMap(employeeDataList);
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), employeeData.getFieldValue()));
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        employee.setEmployeeId(addEmployeeFieldManageBO.getEmployeeId());
        boolean exists = lambdaQuery().eq(HrmEmployee::getJobNumber, employee.getJobNumber()).eq(HrmEmployee::getIsDel, 0)
                .ne(HrmEmployee::getEmployeeId, employee.getEmployeeId()).exists();
        if (exists) {
            throw new CrmException(HrmCodeEnum.JOB_NUMBER_EXISTED, employee.getJobNumber());
        }
        employee.setEntryStatus(EmployeeEntryStatusEnum.在职.getValue());
        employee.setIsDel(0);
        if (employee.getEmploymentForms() == EmploymentFormsEnum.OFFICIAL.getValue()) {
            Integer probation = employee.getProbation();
            if (probation == 0) {
                employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                employee.setBecomeTime(employee.getEntryTime());
            } else {
                LocalDateTime dateTime = LocalDateTimeUtil.offset(employee.getEntryTime().atStartOfDay(), probation, ChronoUnit.MONTHS);
                if (dateTime.isAfter(LocalDateTimeUtil.beginOfDay(LocalDateTime.now()))) {
                    employee.setStatus(EmployeeStatusEnum.TRY_OUT.getValue());
                } else {
                    employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                }
                employee.setBecomeTime(dateTime.toLocalDate());
            }
        }
        updateById(employee);
        abnormalChangeRecordService.addAbnormalChangeRecord(employee.getEmployeeId(), AbnormalChangeType.NEW_ENTRY, LocalDateTime.now());
        HrmEmployee hrmEmployee = getById(addEmployeeFieldManageBO.getEmployeeId());
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(hrmEmployee.getEmployeeId(), hrmEmployee.getEmployeeName());
        operationLog.setOperationInfo("为" + hrmEmployee.getEmployeeName() + "办理入职");

        if (hrmEmployee.getCandidateId() != null) {
            candidateService.lambdaUpdate().set(HrmRecruitCandidate::getStatus, CandidateStatusEnum.HAVE_JOINED.getValue()).set(HrmRecruitCandidate::getEntryTime, new Date())
                    .eq(HrmRecruitCandidate::getCandidateId, hrmEmployee.getCandidateId()).update();
        }
        return operationLog;
    }

    @Override
    public List<HrmEmployeeField> downloadExcelFiled() {
        List<HrmEmployeeField> list = employeeFieldService.lambdaQuery().eq(HrmEmployeeField::getIsImportField, 1).eq(HrmEmployeeField::getIsHidden, 0)
                .list();
        return list.stream().sorted(Comparator.comparingInt(HrmEmployeeField::getSorting)).sorted(Comparator.comparingInt(HrmEmployeeField::getLabel)).collect(Collectors.toList());
    }


    private List<List<String>> head(List<HrmEmployeeField> hrmEmployeeFieldsList, int sheetGroup) {
        List<HrmEmployeeField> hrmEmployeeFields;
        if(EmployeeLableGroup.LABLE_GROUP_1.getValue() == sheetGroup){
            hrmEmployeeFields = hrmEmployeeFieldsList.stream()
                    .filter(t -> t.getLabelGroup() == sheetGroup|| t.getLabelGroup() == EmployeeLableGroup.LABLE_GROUP_11.getValue())
                    .sorted(Comparator.comparing(HrmEmployeeField::getLabelGroup).thenComparing(HrmEmployeeField::getSorting))
                    .collect(Collectors.toList());
        }else{
            hrmEmployeeFields = hrmEmployeeFieldsList.stream()
                    .filter(t -> t.getLabelGroup() == sheetGroup || t.getLabelGroup() == EmployeeLableGroup.LABLE_GROUP_99.getValue())
                    .sorted(Comparator.comparing(HrmEmployeeField::getSorting))
                    .collect(Collectors.toList());
        }
        List<List<String>> list = ListUtils.newArrayList();
        hrmEmployeeFields.forEach(t -> {
            List<String> list1 = ListUtils.newArrayList();
            list1.add(t.getName());
            list.add(list1);
        });
        return list;
    }

    public static JSONObject toJSONObject(Object bean) throws IllegalAccessException {
        Map<String, Object> map = new LinkedHashMap<>();
        Class<?> clazz = bean.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(bean));
        }

        return new JSONObject(map);
    }

    private List<List<Object>> dataList(int sheetGroup, List<EmployeeExportBO> employeeBOList, HashMap<Long, String> deptPath) {
        List<List<Object>> list = ListUtils.newArrayList();
        List<Long> employeeIdList = employeeBOList.stream().map(EmployeeExportBO::getEmployeeId).collect(Collectors.toList());
        if(EmployeeLableGroup.LABLE_GROUP_1.getValue() == sheetGroup){
            List<Long> depotIdList = Lists.newArrayList();
            depotIdList.addAll(employeeBOList.stream().map(EmployeeExportBO::getOrg).collect(Collectors.toList()));
            depotIdList.addAll(employeeBOList.stream().map(EmployeeExportBO::getDept).collect(Collectors.toList()));
            List<SimpleHrmDeptVO> simpleHrmDeptVOS = hrmDeptService.querySimpleDeptList(depotIdList);
            Map<Long, String> depotMap = simpleHrmDeptVOS.stream().collect(Collectors.toMap(SimpleHrmDeptVO::getDeptId, SimpleHrmDeptVO::getDeptName));
            employeeBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                JSONObject jsonObject;
                try {
                    jsonObject = toJSONObject(e);
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                jsonObject.remove("employeeId");
                // 构造司龄
                String companyAge = EmployeeUtil.computeCompanyAge(jsonObject.getInteger("companyAge"));
                jsonObject.put("companyAge", companyAge);
                // 构造任职机构、任职部门
                Long orgId = (Long) jsonObject.get("org");
                Long deptId = (Long) jsonObject.get("dept");
                if (Objects.nonNull(orgId)) {
                    String orgName = depotMap.get(orgId);
                    jsonObject.put("org", orgName);
                }
                if (Objects.nonNull(deptId)){
//                    String deptName = depotMap.get(deptId);
//                    jsonObject.put("dept", deptName);
                    //调整为部门路径
                    jsonObject.put("dept", deptPath.get(deptId));
                }
                jsonObject.put("source", SourceEnum.getNameByValue(jsonObject.getInteger("source")));
                jsonObject.put("sex", SexEnum.parseName(Optional.ofNullable(jsonObject.getInteger("sex")).orElse(-1)));
                jsonObject.put("probation", ProbationEnum.getNameByValue(jsonObject.getInteger("probation")));
                jsonObject.put("highestEducation", EducationEnum.getNameByValue(jsonObject.getInteger("highestEducation")));
                jsonObject.forEach((k, v) -> {data.add(v);});
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_3.getValue() == sheetGroup) {
            List<EmployeeEducationExperienceExportBO> employeeEducationExperienceExportBOList = hrmEmployeeEducationExperienceMapper.searchByEmployeeId(employeeIdList);
            employeeEducationExperienceExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        JSONObject jsonObject = toJSONObject(e);
                        jsonObject.put("education", EducationEnum.getNameByValue(jsonObject.getIntValue("education")));
                        jsonObject.put("degree", DegreeEnum.getNameByValue(jsonObject.getIntValue("degree")));
                        jsonObject.put("teachingMethods", TeachingMethodEnum.getNameByValue(jsonObject.getIntValue("teachingMethods")));
                        jsonObject.forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_7.getValue() == sheetGroup) {
            List<EmployeeContactsExportBO> employeeContactsExportBOList = hrmEmployeeContactsMapper.searchByEmployeeId(employeeIdList);
            employeeContactsExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        toJSONObject(e).forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_4.getValue() == sheetGroup) {
            List<EmployeeWorkExperienceExportBO> employeeWorkExperienceExportBOList = hrmEmployeeWorkExperienceMapper.searchByEmployeeId(employeeIdList);
            employeeWorkExperienceExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        toJSONObject(e).forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_8.getValue() == sheetGroup) {
            List<EmployeeTechnicalExportBO> employeeTechnicalExportBOList = hrmEmployeeTechnicalMapper.searchByEmployeeId(employeeIdList);
            employeeTechnicalExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        toJSONObject(e).forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_5.getValue() == sheetGroup) {
            List<EmployeeCertificateExportBO> employeeCertificateExportBOList = hrmEmployeeCertificateMapper.searchByEmployeeId(employeeIdList);
            employeeCertificateExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        toJSONObject(e).forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_13.getValue() == sheetGroup) {
            List<EmployeeSpecialWorkerExportBO> employeeSpecialWorkerExportBOList = hrmEmployeeSpecialWorkerMapper.searchByEmployeeId(employeeIdList);
            employeeSpecialWorkerExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        toJSONObject(e).forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }
        if (EmployeeLableGroup.LABLE_GROUP_51.getValue() == sheetGroup) {
            List<EmployeeConcurrentPostExportBO> employeeConcurrentPostExportBOList = hrmEmployeeConcurrentPostMapper.searchByEmployeeId(employeeIdList);
            List<Long> depotIdList = Lists.newArrayList();
            depotIdList.addAll(employeeConcurrentPostExportBOList.stream().map(EmployeeConcurrentPostExportBO::getDeptId).collect(Collectors.toList()));
            List<SimpleHrmDeptVO> simpleHrmDeptVOS = hrmDeptService.querySimpleDeptList(depotIdList);
            Map<Long, SimpleHrmDeptVO> depotMap = simpleHrmDeptVOS.stream().collect(Collectors.toMap(SimpleHrmDeptVO::getDeptId, Function.identity()));
            employeeConcurrentPostExportBOList.forEach(e->{
                List<Object> data = ListUtils.newArrayList();
                try {
                    if (Objects.nonNull(e)) {
                        JSONObject jsonObject = toJSONObject(e);
                        Long deptId = (Long) jsonObject.get("deptId");
                        if (Objects.nonNull(deptId)){
                            String deptName = depotMap.get(deptId).getDeptName();
                            jsonObject.put("deptId", deptName);
                        }
                        jsonObject.put("orgId", "");
                        HrmDept hrmDept = hrmDeptMapper.selectById(depotMap.get(deptId).getParentId());
                        if (hrmDept != null) {
                            jsonObject.put("orgId", hrmDept.getName());
                        }
                        jsonObject.forEach((k, v) -> {data.add(v);});
                    }
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
                list.add(data);
            });
        }

        return list;
    }


    @Override
    public void exportExcel(HttpServletResponse response, QueryEmployeePageListBO employeePageListBO) throws IOException {
        // 生成随机密码
        String password = RandomUtil.randomString(6);

        // 创建临时目录和文件
        String tempDir = System.getProperty("java.io.tmpdir");
        String excelFileName = "员工信息_" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
        File excelFile = new File(tempDir, excelFileName);
        if (!excelFile.getParentFile().exists()) {
            excelFile.getParentFile().mkdirs();
        }

        // 写入Excel数据
        try (ExcelWriter excelWriter = EasyExcel.write(excelFile).build()) {
            List<HrmEmployeeField> hrmEmployeeFields = downloadExcelFiled();

            String sortField = StrUtil.isNotEmpty(employeePageListBO.getSortField()) ? StrUtil.toUnderlineCase(employeePageListBO.getSortField()) : null;
            employeePageListBO.setSortField(sortField);
            Collection<Long> employeeIds = employeeUtil.queryUserDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
            if (employeePageListBO.getDeptId() != null) {
                //部门检索
                List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeePageListBO.getDeptId());
                employeePageListBO.setChildrenDeptIdList(deptIds);
                employeePageListBO.setDeptId(null);
            }

            Integer dataAuthType = adminService.queryDataType(UserUtil.getUserId(), MenuIdConstant.EMPLOYEE_MENU_ID).getData();
            // 当数据权限为本部门及下属部门时   可查看兼职人员
            if (DataAuthEnum.THIS_ORG_AND_SUBORDINATE.getValue().equals(dataAuthType)) {
//            Collection<Long> deptIds = new HashSet<>();;
                // 查询数据权限内的部门id  出错   单独写
//            deptIds = employeeUtil.queryDataAuthDeptId(dataAuthType, MenuIdConstant.EMPLOYEE_MENU_ID);
                EmployeeInfo employeeInfo = EmployeeHolder.getEmployeeInfo();
//            List<HrmEmployeeData> deptByEmpIdList = employeeDataService.lambdaQuery()
//                    .eq(HrmEmployeeData::getFieldName, "org")
//                    .eq(HrmEmployeeData::getEmployeeId, employeeInfo.getEmployeeId())
//                    .list();
//            if (CollectionUtils.isNotEmpty(deptByEmpIdList)) {
//                HrmEmployeeData data = deptByEmpIdList.stream().sorted(Comparator.comparing(HrmEmployeeData::getCreateTime).reversed()).findFirst().orElse(null);
//                if (data != null) {
//                    deptIds.add(Long.valueOf(data.getFieldValue()));
//                    deptIds.addAll(hrmDeptService.queryChildDeptId(Collections.singletonList(Long.valueOf(data.getFieldValue()))));
//                }
//            }
                if (employeeInfo.getOrgId() != null) {
                    List<Long> deptIds = hrmDeptService.selectChildrenDeptIds(employeeInfo.getOrgId());
                    List<HrmEmployeeConcurrentPost> concurrentPostList = concurrentPostService.lambdaQuery().in(HrmEmployeeConcurrentPost::getDeptId, deptIds).ne(HrmEmployeeConcurrentPost::getEntryStatus, "离职").list();
                    List<Long> concurrentPostEmployeeIdList = concurrentPostList.stream()
                            .map(HrmEmployeeConcurrentPost::getEmployeeId)
                            .filter(employeeId -> !employeeIds.contains(employeeId))
                            .collect(Collectors.toList());
                    if (!concurrentPostEmployeeIdList.isEmpty()) {
                        employeeIds.addAll(concurrentPostEmployeeIdList);
                    }
                }
            }

            List<EmployeeExportBO> employeeBOList;

            if (StrUtil.isNotEmpty(employeePageListBO.getEmployeeName())) {
                employeePageListBO.setPage(1L);
                employeePageListBO.setLimit(this.lambdaQuery().count());
                BasePage<Map<String, Object>> page = this.fullTextSearch(employeePageListBO, employeeIds);
                List<Map<String, Object>> list = page.getList();
                List<Long> empIds = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(list)) {
                    empIds = list.stream().map(map -> Long.parseLong(String.valueOf(map.get("employeeId")))).collect(Collectors.toList());
                }
                empIds.add(-1L);
                QueryEmployeePageListBO pageListBO = new QueryEmployeePageListBO();
                pageListBO.setSortField(employeePageListBO.getSortField());
                employeeBOList = employeeMapper.search(pageListBO, empIds);
            } else {
                // 查询员工主表业务数据
                employeeBOList = employeeMapper.search(employeePageListBO, employeeIds);
            }

            // 添加导出数据大小到响应头
            response.setHeader("exportSize", String.valueOf(employeeBOList.size()));

            //获取所有部门路径
            HashMap<Long, String> deptPath = hrmDeptService.getAllDeptPath();
            // 获取枚举值
            EmployeeLableGroup[] values = EmployeeLableGroup.values();
            for (int i = 0; i < values.length; i++) {
                EmployeeLableGroup employeeLableGroup = values[i];
                if (employeeLableGroup.getStatus() != 1 || employeeLableGroup.getValue() == EmployeeLableGroup.LABLE_GROUP_11.getValue()) {
                    continue;
                }
                // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变，我这里为了方便 所以用的同一个class
                // 实际上可以一直变
                WriteSheet writeSheet = EasyExcel.writerSheet(i, employeeLableGroup.getName()).head(head(hrmEmployeeFields, employeeLableGroup.getValue())).build();
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                excelWriter.write(dataList(employeeLableGroup.getValue(), employeeBOList, deptPath), writeSheet);
            }
        }

        // 创建zip文件
        String zipFileName = "员工信息_" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".zip";
        File zipFile = new File(tempDir, zipFileName);

        // 使用密码加密压缩Excel文件
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(EncryptionMethod.AES);

        try (ZipFile zip = new ZipFile(zipFile, password.toCharArray())) {
            zip.addFile(excelFile, zipParameters);
        }

        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8"));

        // 写入响应流
        try (InputStream is = new FileInputStream(zipFile);
             OutputStream os = response.getOutputStream()) {
            // 将密码写入响应头的Content-Description字段
            response.setHeader("Content-Description", password);
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            os.flush();
        } finally {
            // 清理临时文件
            if (excelFile.exists()) {
                excelFile.delete();
            }
            if (zipFile.exists()) {
                zipFile.delete();
            }
        }
    }

    @Override
    public List<Map<String, Object>> export(QueryEmployeePageListBO employeePageListBO) {
        List<Map<String, Object>> list = employeeMapper.export(employeePageListBO);
        list.forEach(map -> {
            Long deptId = (Long) map.remove("deptId");
            Integer employmentForms = (Integer) map.remove("employmentForms");
            Integer status = (Integer) map.remove("status");
            Integer idType = (Integer) map.remove("idType");
            HrmDept hrmDept = hrmDeptService.getById(deptId);
            if (hrmDept != null) {
                map.put("deptName", hrmDept.getName());
            } else {
                map.put("deptName", "");
            }
            map.put("employmentForms", EmploymentFormsEnum.parseName(employmentForms));
            map.put("status", EmployeeStatusEnum.parseName(status));
            if (idType == null) {
                map.put("idType", "");
            } else {
                map.put("idType", IdTypeEnum.parseName(idType));
            }
        });
        return list;
    }

    @Override
    public Integer queryFieldValueNoDelete(List<HrmEmployeeField> uniqueList) {
        return employeeMapper.queryFieldValueNoDelete(uniqueList);
    }

    @Override
    public List<Long> queryToInByMonth(int year, int month) {
        return employeeMapper.queryToInByMonth(year, month);
    }

    @Override
    public List<Long> queryToLeaveByMonth(int year, int month) {
        return employeeMapper.queryToLeaveByMonth(year, month);
    }

    @Override
    public List<Long> queryToCorrectCount() {
        return employeeMapper.queryToCorrectCount();
    }


    @Override
    public List<Long> queryBirthdayEmp() {
        DateTime start = DateUtil.beginOfMonth(new Date());
        DateTime end = DateUtil.endOfMonth(new Date());
        DateRange dateTimes = new DateRange(start, end, DateField.DAY_OF_YEAR);
        List<String> lunarList = new ArrayList<>();
        List<String> solarList = new ArrayList<>();
        dateTimes.forEach(dateTime -> {
            String[] strings = queryBirthdayTime(dateTime);
            lunarList.add(strings[0]);
            solarList.add(strings[1]);
        });
        return employeeMapper.queryBirthdayEmp(lunarList, solarList);
    }

    @Override
    public List<HrmEmployee> queryBirthdayListByTime(LocalDate time, Collection<Long> employeeIds) {
        String[] strings = queryBirthdayTime(Timestamp.valueOf(time.atStartOfDay()));
        return employeeMapper.queryBirthdayListByTime(strings[0], strings[1], employeeIds);
    }

    @Override
    public List<HrmEmployee> queryEntryEmpListByTime(LocalDate time, Collection<Long> employeeIds) {
        return employeeMapper.queryEntryEmpListByTime(time, employeeIds);
    }

    private String[] queryBirthdayTime(Date date) {
        ChineseDate chineseDate = new ChineseDate(date);
        String lunarMonth = String.valueOf(chineseDate.getMonth());
        String lunarDay = String.valueOf(chineseDate.getDay());
        if (lunarMonth.length() == 1) {
            lunarMonth = "0" + lunarMonth;
        }
        if (lunarDay.length() == 1) {
            lunarDay = "0" + lunarDay;
        }
        LocalDate localDate = LocalDate.parse(DateUtil.format(date, "yyyy-MM-dd"));
        String solarMonth = String.valueOf(localDate.getMonthValue());
        String solarDay = String.valueOf(localDate.getDayOfMonth());
        if (solarMonth.length() == 1) {
            solarMonth = "0" + solarMonth;
        }
        if (solarDay.length() == 1) {
            solarDay = "0" + solarDay;
        }
        String lunarBirthday = lunarMonth + lunarDay;
        String solarBirthday = solarMonth + solarDay;
        return new String[]{lunarBirthday, solarBirthday};
    }

    @Override
    public List<HrmEmployee> queryBecomeEmpListByTime(LocalDate time, Collection<Long> employeeIds) {
        return employeeMapper.queryBecomeEmpListByTime(time, employeeIds);
    }

    @Override
    public List<HrmEmployee> queryLeaveEmpListByTime(LocalDate time, Collection<Long> employeeIds) {
        return employeeMapper.queryLeaveEmpListByTime(time, employeeIds);
    }

    @Override
    public DeptEmployeeListVO queryDeptEmployeeList(Long deptId) {
        DeptEmployeeListVO deptEmployeeListVO = new DeptEmployeeListVO();
        List<DeptEmployeeVO> deptList = hrmDeptService.queryDeptEmployeeList();
        createTree(deptId, deptList);
        List<SimpleHrmEmployeeVO> employeeList = employeeMapper.querySimpleEmpByDeptId(deptId);
        List<DeptEmployeeVO> collect = deptList.stream().filter(dept -> dept.getParentId().equals(deptId)).collect(Collectors.toList());
        deptEmployeeListVO.setDeptList(collect);
        deptEmployeeListVO.setEmployeeList(employeeList);
        return deptEmployeeListVO;
    }


    @Override
    public DeptEmployeeListVO queryInspectionDeptEmployeeList(Long deptId) {
        Integer dataAuthType = adminService.queryDataType(UserUtil.getUserId(), MenuIdConstant.CREATE_ACHIEVEMENT_SETTING_MENU_ID).getData();
        Collection<Long> deptIds = null;
        if (!EmployeeHolder.isHrmAdmin() && !DataAuthEnum.ALL.getValue().equals(dataAuthType)) {
            deptIds = employeeUtil.queryDataAuthDeptId(dataAuthType, MenuIdConstant.CREATE_ACHIEVEMENT_SETTING_MENU_ID);
        } else {
            List<HrmDept> hrmDeptList = hrmDeptService.list();
            if (CollectionUtil.isNotEmpty(hrmDeptList)) {
                deptIds = hrmDeptList.stream().map(HrmDept::getDeptId).collect(Collectors.toList());
            }
        }
        DeptEmployeeListVO deptEmployeeListVO = new DeptEmployeeListVO();
        //查询所有部门下的所有员工列表
        List<DeptEmployeeVO> deptList = hrmDeptService.queryDeptEmployeeList();
        //查询当前部门下的员工列表
        List<SimpleHrmEmployeeVO> employeeList = employeeMapper.querySimpleEmpByDeptId(deptId);


        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.CREATE_ACHIEVEMENT_SETTING_MENU_ID);
        List<SimpleHrmEmployeeVO> empFilterList = employeeList.stream().filter(employeeVO -> {
            return employeeIds.contains(employeeVO.getEmployeeId());
        }).collect(Collectors.toList());

        //查询指定部门的下级部门并返回树结构
        List<DeptEmployeeVO> treeDept = createTreeInspection(deptId, deptList);
        DeptEmployeeVO root = new DeptEmployeeVO();

        DeptEmployeeVO node = new DeptEmployeeVO();
        node.setChildren(treeDept);
        //上一步得到的部门树结构是没有经过权限过滤的，这一步对权限进行过滤
        if (CollUtil.isNotEmpty(treeDept)) {
            filterNode(root, node, deptIds);
        }
//        createTree(deptId, treeDept);
        deptEmployeeListVO.setDeptList(root.getChildren());
        deptEmployeeListVO.setEmployeeList(empFilterList);

        return deptEmployeeListVO;
    }

    private List<DeptEmployeeVO> createTree(Long pid, List<DeptEmployeeVO> deptList) {
        List<DeptEmployeeVO> treeDept = new ArrayList<>();
        for (DeptEmployeeVO dept : deptList) {
            if (pid.equals(dept.getParentId())) {
                treeDept.add(dept);
                List<DeptEmployeeVO> children = createTree(dept.getDeptId(), deptList);
                if (CollUtil.isNotEmpty(children)) {
                    for (DeptEmployeeVO child : children) {
                        dept.setAllNum(dept.getAllNum() + child.getAllNum());
                    }
                    dept.setHasChildren(1);
                } else {
                    dept.setHasChildren(0);
                }
            }
        }
        return treeDept;
    }


    private List<DeptEmployeeVO> createTreeInspection(Long pid, List<DeptEmployeeVO> deptList) {
        List<DeptEmployeeVO> treeDept = new ArrayList<>();
        for (DeptEmployeeVO dept : deptList) {
            if (pid.equals(dept.getParentId())) {
                treeDept.add(dept);
                List<DeptEmployeeVO> children = createTreeInspection(dept.getDeptId(), deptList);
                dept.setChildren(children);
            }
        }
        return treeDept;
    }


    /**
     * 树结构根据指定部门重组
     *
     * @param result      返回接过
     * @param node        全部树结构
     * @param findDeptIds 需要筛选的部门id
     */
    private static void filterNode(DeptEmployeeVO result, DeptEmployeeVO node, Collection<Long> findDeptIds) {
        List<DeptEmployeeVO> childList = node.getChildren();
        if (findDeptIds.contains(node.getDeptId())) {
            DeptEmployeeVO newNode = BeanUtil.copyProperties(node, DeptEmployeeVO.class);
            newNode.setChildren(null);
            if (CollUtil.isEmpty(result.getChildren())) {
                result.setChildren(Lists.newArrayList(newNode));
            } else {
                List<DeptEmployeeVO> childList1 = result.getChildren();
                childList1.add(newNode);
            }
            findDeptIds.remove(node.getDeptId());
            if (CollUtil.isEmpty(childList)) {
                return;
            }
            for (DeptEmployeeVO deptVO : childList) {
                filterNode(newNode, deptVO, findDeptIds);
            }
        } else {
            if (CollUtil.isEmpty(childList)) {
                return;
            }
            for (DeptEmployeeVO deptVO : childList) {
                filterNode(result, deptVO, findDeptIds);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OperationLog> adminAddEmployee(List<AddEmployeeBO> employeeBOS) {
        List<OperationLog> operationLogList = new ArrayList<>();
        for (AddEmployeeBO employeeBO : employeeBOS) {
            employeeBO.setEntryStatus(EmployeeEntryStatusEnum.在职.getValue());
            operationLogList.addAll(add(employeeBO));
        }
        return operationLogList;
    }

    @Override
    public Set<SimpleHrmEmployeeVO> queryDeptUserListByUser(DeptUserListByUserBO deptUserListByUserBO) {
        Set<SimpleHrmEmployeeVO> employeeVOS = new HashSet<>();
        if (CollUtil.isNotEmpty(deptUserListByUserBO.getDeptIdList())) {
            List<HrmEmployee> userList = findChildUserList(deptUserListByUserBO.getDeptIdList());
            List<SimpleHrmEmployeeVO> hrmSimpleEmpVOS = TransferUtil.transferList(userList, SimpleHrmEmployeeVO.class);
            employeeVOS.addAll(hrmSimpleEmpVOS);
        }
        if (CollUtil.isNotEmpty(deptUserListByUserBO.getEmployeeIdList())) {
            List<HrmEmployee> userList = query().select("employee_id", "employee_name", "post", "sex", "mobile", "email").in("employee_id", deptUserListByUserBO.getEmployeeIdList())
                    .eq("is_del", 0).in("entry_status", 1, 3).list();
            List<SimpleHrmEmployeeVO> hrmSimpleUserVOS = TransferUtil.transferList(userList, SimpleHrmEmployeeVO.class);
            employeeVOS.addAll(hrmSimpleUserVOS);
        }
        return employeeVOS;
    }

    private List<HrmEmployee> findChildUserList(List<Long> deptIds) {
        List<HrmEmployee> empList = new ArrayList<>();
        for (Long deptId : deptIds) {
            List<HrmEmployee> list = query().select("employee_id", "employee_name", "post", "sex", "mobile", "email").eq("dept_id", deptId)
                    .in("entry_status", 1, 3).eq("is_del", 0).list();
            empList.addAll(list);
            List<HrmDept> childList = hrmDeptService.lambdaQuery().select(HrmDept::getDeptId).eq(HrmDept::getParentId, deptId).list();
            if (CollUtil.isNotEmpty(childList)) {
                List<Long> childDeptIds = childList.stream().map(HrmDept::getDeptId).collect(Collectors.toList());
                empList.addAll(findChildUserList(childDeptIds));
            }
        }
        return empList;
    }

    @Override
    public Set<Long> filterDeleteEmployeeIds(Set<Long> employeeIds) {
        return employeeMapper.filterDeleteEmployeeIds(employeeIds);
    }

    @Override
    public List<SimpleHrmEmployeeVO> queryAllSimpleEmployeeList(Collection<Long> employeeIds) {
        if (CollUtil.isEmpty(employeeIds)) {
            return new ArrayList<>();
        }
        List<HrmEmployee> list = lambdaQuery().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName, HrmEmployee::getEntryStatus, HrmEmployee::getIsDel)
                .in(HrmEmployee::getEmployeeId, employeeIds).list();
        return list.stream().map(this::transferSimpleEmp).collect(Collectors.toList());
    }

    @Override
    public Set<Long> queryChildEmployeeId(List<Long> employeeIds) {
        Set<Long> result = new HashSet<>(employeeIds);
        if (CollUtil.isNotEmpty(employeeIds)) {
            employeeIds.forEach(employeeId -> {
                List<Long> collect = lambdaQuery().select(HrmEmployee::getEmployeeId).eq(HrmEmployee::getParentId, employeeId).list()
                        .stream().map(HrmEmployee::getEmployeeId).collect(Collectors.toList());
                result.addAll(queryChildEmployeeId(collect));
            });
        }
        return result;
    }

    @Override
    public Set<String> queryEntryStatusList(QueryNotesStatusBO queryNotesStatusBO, Collection<Long> employeeIds) {
        return employeeMapper.queryEntryStatusList(queryNotesStatusBO, employeeIds);
    }

    @Override
    public Set<String> queryBecomeStatusList(QueryNotesStatusBO queryNotesStatusBO, Collection<Long> employeeIds) {
        return employeeMapper.queryBecomeStatusList(queryNotesStatusBO, employeeIds);
    }

    @Override
    public Set<String> queryLeaveStatusList(QueryNotesStatusBO queryNotesStatusBO, Collection<Long> employeeIds) {
        return employeeMapper.queryLeaveStatusList(queryNotesStatusBO, employeeIds);
    }

    @Override
    public List<HrmModelFiledVO> queryEmployeeField(Integer entryStatus) {
        List<HrmModelFiledVO> filedVOS = employeeFieldService.queryField(entryStatus);
        return filedVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OperationLog> addEmployeeField(AddEmployeeFieldManageBO addEmployeeFieldManageBO) {
        String jobNumber = addEmployeeFieldManageBO.getJobNumber();
        if (StrUtil.isNotEmpty(jobNumber)) {
            boolean exists = lambdaQuery().eq(HrmEmployee::getIsDel, 0).eq(HrmEmployee::getJobNumber, jobNumber).exists();
            if (exists) {
                throw new CrmException(HrmCodeEnum.JOB_NUMBER_EXISTED, jobNumber);
            }
        }
        List<OperationLog> operationLogList = new ArrayList<>();

        if (addEmployeeFieldManageBO.getCandidateId() != null) {
            if (addEmployeeFieldManageBO.getEntryStatus() == 1) {
                UpdateCandidateStatusBO updateCandidateStatusBO = new UpdateCandidateStatusBO();
                updateCandidateStatusBO.setCandidateIds(Collections.singletonList(addEmployeeFieldManageBO.getCandidateId()));
                updateCandidateStatusBO.setStatus(CandidateStatusEnum.HAVE_JOINED.getValue());
                operationLogList.addAll(candidateActionRecordService.updateCandidateStatusRecord(updateCandidateStatusBO));
                candidateService.lambdaUpdate().set(HrmRecruitCandidate::getStatus, CandidateStatusEnum.HAVE_JOINED.getValue())
                        .set(HrmRecruitCandidate::getStatusUpdateTime, new Date())
                        .set(HrmRecruitCandidate::getEntryTime, new Date())
                        .eq(HrmRecruitCandidate::getCandidateId, addEmployeeFieldManageBO.getCandidateId()).update();

            } else {
                UpdateCandidateStatusBO updateCandidateStatusBO = new UpdateCandidateStatusBO();
                updateCandidateStatusBO.setCandidateIds(Collections.singletonList(addEmployeeFieldManageBO.getCandidateId()));
                updateCandidateStatusBO.setStatus(CandidateStatusEnum.PENDING_ENTRY.getValue());
                operationLogList.addAll(candidateActionRecordService.updateCandidateStatusRecord(updateCandidateStatusBO));
                candidateService.lambdaUpdate().set(HrmRecruitCandidate::getStatus, CandidateStatusEnum.PENDING_ENTRY.getValue())
                        .set(HrmRecruitCandidate::getStatusUpdateTime, new Date())
                        .eq(HrmRecruitCandidate::getCandidateId, addEmployeeFieldManageBO.getCandidateId()).update();
            }

        }
        // 员工个人信息自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeFieldList = addEmployeeFieldManageBO.getEmployeeFieldList();
        // 员工岗位自定义字段列表
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> postFieldList = addEmployeeFieldManageBO.getPostFieldList();
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> employeeDataList = Stream.concat(employeeFieldList.stream(), postFieldList.stream()).collect(Collectors.toList());
        Map<FiledIsFixedEnum, List<AddEmployeeFieldManageBO.EmployeeFieldBO>> isFixedMap = getIsFixedMap(employeeDataList);
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        List<AddEmployeeFieldManageBO.EmployeeFieldBO> noFixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.NO_FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), employeeData.getFieldValue()));
        List<String> selfDef = Lists.newArrayList("dept","org");
        for (AddEmployeeFieldManageBO.EmployeeFieldBO item : noFixedEmployeeData) {
            if(selfDef.contains(item.getFieldName())){
                jsonObject.put(item.getFieldName()+"Id",item.getFieldValue());
            }
        }
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        if (addEmployeeFieldManageBO.getCandidateId() != null) {
            HrmRecruitCandidate candidate = candidateService.getById(addEmployeeFieldManageBO.getCandidateId());
            employee.setChannelId(candidate.getChannelId());
            employee.setCandidateId(addEmployeeFieldManageBO.getCandidateId());
        }

        employee.setEntryStatus(addEmployeeFieldManageBO.getEntryStatus());
        employee.setStatus(1);
        if (null == employee.getCompanyAgeStartTime()) {
            employee.setCompanyAgeStartTime(employee.getEntryTime());
        }
        transferEmployee(employee);
        save(employee);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        List<HrmEmployeeData> hrmEmployeeData = isFixedMap.get(FiledIsFixedEnum.NO_FIXED).stream()
                .map(field -> {
                    Object value = field.getFieldValue();
                    if (value == null) {
                        value = "";
                    }
                    field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                    return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                }).collect(Collectors.toList());
        if (!hrmEmployeeData.isEmpty()) {
            List<HrmEmployeeData> personalData = hrmEmployeeData.stream().filter(employeeData -> employeeData.getLabelGroup().equals(LabelGroupEnum.PERSONAL.getValue())).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(personalData, LabelGroupEnum.PERSONAL, employee.getEmployeeId());
            List<HrmEmployeeData> postData = hrmEmployeeData.stream().filter(employeeData -> employeeData.getLabelGroup().equals(LabelGroupEnum.POST.getValue())).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(postData, LabelGroupEnum.POST, employee.getEmployeeId());
        }
        boolean exists = employeeFieldService.query().eq("field_name", "flied_kwbova").eq("label_group", LabelGroupEnum.COMMUNICATION.getValue()).eq("type", FieldTypeEnum.MOBILE.getValue()).exists();
        if (exists) {
            //若是存在自定义手机号码字段，则进行更新
            HrmEmployee hrmEmployee = employeeMapper.selectById(employee.getEmployeeId());
            JSONObject employeeModel = BeanUtil.copyProperties(hrmEmployee, JSONObject.class);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employee.getEmployeeId());
            List<InformationFieldVO> communicationInformation = transferInformation(employeeModel, LabelGroupEnum.COMMUNICATION, fieldValueList);
            List<InformationFieldVO> informationFieldVOS = communicationInformation.stream().collect(Collectors.groupingBy(employeeData -> FiledIsFixedEnum.parse(employeeData.getIsFixed()))).get(FiledIsFixedEnum.NO_FIXED);
            String fliedKwbova = "flied_kwbova";
            List<HrmEmployeeData> hrmEmployeeInformationData = informationFieldVOS.stream()
                    .map(field -> {
                        if (fliedKwbova.equals(field.getFieldName()) && field.getType().equals(FieldTypeEnum.MOBILE.getValue())) {
                            field.setFieldValue(employee.getMobile());
                            field.setFieldValueDesc(employee.getMobile());
                        }
                        Object value = field.getFieldValue();
                        if (value == null) {
                            value = "";
                        }
                        field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                        return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                    }).collect(Collectors.toList());
            employeeFieldService.saveEmployeeField(hrmEmployeeInformationData, LabelGroupEnum.COMMUNICATION, employee.getEmployeeId());
        }
        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.PERSONAL, employee.getEmployeeId());
        operationLog.setOperationInfo(content.getDetail());
        if (addEmployeeFieldManageBO.getEntryStatus() == 1) {
            abnormalChangeRecordService.addAbnormalChangeRecord(employee.getEmployeeId(), AbnormalChangeType.NEW_ENTRY, LocalDateTime.now());
        }
        Boolean res = false;
        //保存入职流程
        if(addEmployeeFieldManageBO.getEntryStatus()== EmployeeEntryStatusEnum.在职.getValue()){
            employee.setAddEmployeeFieldManageBO(addEmployeeFieldManageBO);
            res = saveEntryExamine(employee);
        }
        if (!res){
            //保存员工入职资料
            List<EmployeeMaterialBO> materialList = addEmployeeFieldManageBO.getMaterialList();
            if (materialList != null && !materialList.isEmpty()){
                for (EmployeeMaterialBO materialBO : materialList) {
                    AddFileBO addFileBO = new AddFileBO();
                    addFileBO.setEmployeeId(employee.getEmployeeId());
                    addFileBO.setSubType(materialBO.getSubType());
                    addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                    hrmEmployeeFileService.addFile(addFileBO);
                }
            }
        }
        //发送通知
        AdminMessage adminMessage = new AdminMessage();
        adminMessage.setCreateUser(UserUtil.getUserId());
        adminMessage.setCreateTime(DateUtil.formatDateTime(new Date()));
        adminMessage.setRecipientUser(EmployeeCacheUtil.getUserId(employee.getEmployeeId()));
        adminMessage.setLabel(8);
        adminMessage.setType(AdminMessageEnum.HRM_EMPLOYEE_OPEN.getType());
        messageService.save(adminMessage);

        if (operationLogList.isEmpty()) {
            operationLogList.add(operationLog);
        }
        //更新es员工数据
        updateESAfterCommit(employee.getEmployeeId());
        //保存员工异动记录
        HrmEmployeeDataMobilizeRecord record = new HrmEmployeeDataMobilizeRecord();
        record.setEmployeeId(employee.getEmployeeId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setType(EmployeeDataMobilizeType.ENTRY.getValue());
        record.setRemark(String.format("员工 %s 办理了 %s 的人员入职。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        hrmEmployeeDataMobilizeRecordService.addMobilizeRecord(record);
        return operationLogList;
    }

    /**
     *  @author qun.xu
     *  @date 2024-03-18
     *  @desc 发起业务入职流程
     */
    private Boolean saveEntryExamine(HrmEmployee employee){
        Boolean examineRes = hrmExamineService.saveHrmEntryExamine(employee);
        //在职,并执行成功，将人员的状态修改待入职
        if(examineRes){
            HrmEmployee update = new HrmEmployee();
            update.setEntryStatus(EmployeeEntryStatusEnum.入职审批中.getValue());
            update.setEmployeeId(employee.getEmployeeId());
            this.updateById(update);
        }
        return examineRes;
    }

    /**
     * 员工基本信息修改审核
     * @param employee
     * @param updateData
     * @return
     */
    private Boolean saveEmployeeInfoChangeExamine(HrmEmployee employee, UpdateInformationBO updateData) {
        return hrmExamineService.saveHrmEmployeeInfoChangeExamine(employee, JSON.toJSONString(updateData));
    }

    /**
     * 员工关键字段修改审核
     * @param employee
     * @param informationBOMap
     * @return
     */
    private Boolean saveEmployeeKeyFieldChangeExamine(HrmEmployee employee, Map<String, Object> informationBOMap) {
        return hrmExamineService.saveEmployeeKeyFieldChangeExamine(employee, JSON.toJSONString(informationBOMap));
    }

    /**
     * 员工职位层级调整审核
     * @param employee
     * @param employeePostLevelVo
     * @return
     */
    private Boolean saveEmployeePostLevelChangeExamine(HrmEmployee employee, EmployeePostLevelVo employeePostLevelVo) {
        return hrmExamineService.saveEmployeePostLevelChangeExamine(employee, JSON.toJSONString(employeePostLevelVo));
    }


    /**
     * @author qun.xu
     * 保存员工变动流程
     */
    private Boolean saveChangeExamine(Long employeeId,HrmEmployeeChangeRecord changeRecord){
        HrmEmployee employee  = this.getById(employeeId);
        List<JSONObject> fieldDatalist = employeeDataService.queryFiledListByEmployeeId(employee.getEmployeeId());
        List<JSONObject> orgField = fieldDatalist.stream().filter(o -> o.getString("fieldName").equals("org")).collect(Collectors.toList());
        List<JSONObject> deptField = fieldDatalist.stream().filter(o -> o.getString("fieldName").equals("dept")).collect(Collectors.toList());
        if(ObjectUtils.isNotEmpty(orgField)){
            employee.setOrgId(orgField.get(0).getLong("fieldValue"));
        }
        if(ObjectUtils.isNotEmpty(deptField)){
            employee.setDeptId(deptField.get(0).getLong("fieldValue"));
        }
        if (changeRecord != null){
            employee.setChangeRecord(changeRecord);
        }
        Boolean examineRes =  false;
        //判断是否是同一单位
        if(changeRecord.getNewOrg()!=null && changeRecord.getNewDept()!=null){
              //跨单位流程
            if(!changeRecord.getNewOrg().equals(employee.getOrgId())){
                examineRes =    hrmExamineService.saveHrmEmployeeChangeExamine(employee);
            }else if(changeRecord.getNewOrg().equals(employee.getOrgId()) && (!changeRecord.getNewDept().equals( employee.getDeptId()))){
                //内部流程
                examineRes =   hrmExamineService.saveHrmEmployeeChangeExamineInner(employee);
            }
        }
        //调动审批中,并执行成功，将人员的状态修改调动审批中
        if(examineRes){
            HrmEmployee update = new HrmEmployee();
            update.setEntryStatus(EmployeeEntryStatusEnum.调动审批中.getValue());
            update.setEmployeeId(employee.getEmployeeId());
            this.updateById(update);
        }
        return examineRes;
    }

    @Override
    public void recordToFormType(InformationFieldVO record, FieldEnum typeEnum) {
        record.setFormType(typeEnum.getFormType());
        switch (typeEnum) {
            case CHECKBOX:
                String contains = "[]";
                if (record.getDefaultValue().toString().contains(contains)) {
                    record.setDefaultValue("");
                }
                record.setDefaultValue(StrUtil.splitTrim((CharSequence) record.getDefaultValue().toString(), Const.SEPARATOR));
                record.setFieldValue(StrUtil.splitTrim((CharSequence) record.getFieldValue(), Const.SEPARATOR));
            case SELECT:
                if (Objects.equals(record.getRemark(), FieldEnum.OPTIONS_TYPE.getFormType())) {
                    if (CollUtil.isEmpty(record.getOptionsData())) {
                        JSONObject optionsData = JSON.parseObject(record.getOptions());
                        record.setOptionsData(optionsData);
                        record.setSetting(new ArrayList<>(optionsData.keySet()));
                    }
                } else {
                    if (CollUtil.isEmpty(record.getSetting())) {
                        try {
                            String dtStr = Optional.ofNullable(record.getOptions()).orElse("").toString();
                            List<Object> jsonArrayList = JSON.parseObject(dtStr, List.class);
                            record.setSetting(jsonArrayList);
                        } catch (Exception e) {
                            record.setSetting(new ArrayList<>(StrUtil.splitTrim(record.getOptions(), Const.SEPARATOR)));
                        }
                    }
                }
                break;
            case DATE_INTERVAL:
                String dataValueStr = Optional.ofNullable(record.getDefaultValue()).orElse("").toString();
                if (StrUtil.isNotEmpty(dataValueStr)) {
                    record.setDefaultValue(StrUtil.split(dataValueStr, Const.SEPARATOR));
                }
                if (record.getFieldValue() instanceof String) {
                    record.setFieldValue(StrUtil.split((String) record.getFieldValue(), Const.SEPARATOR));
                }
                break;
            case USER:
            case STRUCTURE:
                record.setDefaultValue(new ArrayList<>(0));
                break;
            case AREA:
                String defaultValue = Optional.ofNullable(record.getDefaultValue()).orElse("").toString();
                record.setDefaultValue(JSON.parse(defaultValue));
                if (record.getFieldValue() instanceof String) {
                    String value = Optional.ofNullable(record.getFieldValue()).orElse("").toString();
                    record.setFieldValue(value);
                }
                break;
            case DETAIL_TABLE:
                if (CollUtil.isEmpty(record.getFieldExtendList())) {
                    record.setFieldExtendList(hrmFieldExtendService.queryHrmFieldExtend(record.getFieldId()));
                }
                record.setFieldValue(employeeFieldService.convertValueByFormType(record.getFieldValue(), typeEnum));
                break;
            case DESC_TEXT:
                record.setFieldValue(record.getDefaultValue());
                break;
            default:
                record.setSetting(new ArrayList<>());
                break;
        }
    }

    @Override
    public SimpleHrmEmployeeVO querySimpleEmployee(Long employeeId) {
        if (employeeId == null) {
            return new SimpleHrmEmployeeVO();
        }
        HrmEmployee hrmEmployee = lambdaQuery().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName)
                .eq(HrmEmployee::getEmployeeId, employeeId).eq(HrmEmployee::getIsDel, 0).one();
        return BeanUtil.copyProperties(hrmEmployee, SimpleHrmEmployeeVO.class);
    }

    /**
     * 查询部门员工列表(考勤打卡调用)
     *
     * @param deptId
     * @return
     */
    @Override
    public DeptEmployeeListVO queryAttendDeptEmployeeList(Long deptId) {
        Integer dataAuthType = adminService.queryDataType(UserUtil.getUserId(), MenuIdConstant.ATTENDANCE_MENU_ID).getData();
        Collection<Long> deptIds = null;
        if (!EmployeeHolder.isHrmAdmin() && !DataAuthEnum.ALL.getValue().equals(dataAuthType)) {
            deptIds = employeeUtil.queryDataAuthDeptId(dataAuthType, MenuIdConstant.ATTENDANCE_MENU_ID);
        } else {
            List<HrmDept> hrmDeptList = hrmDeptService.list();
            if (CollectionUtil.isNotEmpty(hrmDeptList)) {
                deptIds = hrmDeptList.stream().map(HrmDept::getDeptId).collect(Collectors.toList());
            }
        }
        DeptEmployeeListVO deptEmployeeListVO = new DeptEmployeeListVO();
        //查询所有部门下的所有员工列表
        List<DeptEmployeeVO> deptList = hrmDeptService.queryDeptEmployeeList();
        //查询当前部门下的员工列表
        List<SimpleHrmEmployeeVO> employeeList = employeeMapper.querySimpleEmpByDeptId(deptId);
        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.ATTENDANCE_MENU_ID);
        List<SimpleHrmEmployeeVO> empFilterList = employeeList.stream().filter(employeeVO -> {
            return employeeIds.contains(employeeVO.getEmployeeId());
        }).collect(Collectors.toList());
        //查询指定部门的下级部门并返回树结构
        List<DeptEmployeeVO> treeDept = createTreeInspection(deptId, deptList);
        DeptEmployeeVO root = new DeptEmployeeVO();
        DeptEmployeeVO node = new DeptEmployeeVO();
        node.setChildren(treeDept);
        if (CollUtil.isNotEmpty(treeDept)) {
            filterNode(root, node, deptIds);
        }
        deptEmployeeListVO.setDeptList(root.getChildren());
        deptEmployeeListVO.setEmployeeList(empFilterList);
        return deptEmployeeListVO;
    }

    /**
     * 查询考勤范围可查询的所有员工
     *
     * @param employeeName
     * @return
     */
    @Override
    public List<SimpleHrmEmployeeVO> queryAttendanceAllEmployeeList(String employeeName) {
        Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
        LambdaQueryWrapper<HrmEmployee> wrapper = new QueryWrapper<HrmEmployee>().lambda().select(HrmEmployee::getEmployeeId, HrmEmployee::getEmployeeName, HrmEmployee::getPost,
                HrmEmployee::getEntryStatus, HrmEmployee::getIsDel, HrmEmployee::getDeptId).eq(HrmEmployee::getIsDel, 0).like(StrUtil.isNotEmpty(employeeName), HrmEmployee::getEmployeeName, employeeName);
        List<HrmEmployee> hrmEmployeeList = this.list(wrapper);
        List<SimpleHrmEmployeeVO> simpleHrmEmployeeVOList = new ArrayList<>();
        for (HrmEmployee employee : hrmEmployeeList) {
            if (employeeIds.contains(employee.getEmployeeId())) {
                simpleHrmEmployeeVOList.add(transferSimpleEmp(employee));
            }
        }
        return simpleHrmEmployeeVOList;
    }

    @Override
    public EmployeeInfo queryEmployeeInfoByIdNumber(String idNumber) {
        return employeeMapper.queryEmployeeInfoByIdNumber(idNumber);
    }

    @Override
    public void employeeMove(EmployeeMoveBO employeeMoveBO) {

        HrmEmployee employee = new HrmEmployee();
        if (employeeMoveBO.getFrontId() != 0) {
            //前面员工
            HrmEmployee hrmEmployee = employeeMapper.selectById(employeeMoveBO.getFrontId());
            employee.setSortId(hrmEmployee.getSortId() + 1);
        }else {
            //前面不存在员工 第一个员工
            employee.setSortId(0L);
        }
        employeeMapper.updateEmployeeSortById(employee);
        employeeMapper.updateById(employee);
    }

    @Override
    public Set<Long> selectEmployeeListByDeptIds(Set<Long> deptIds) {
        return employeeMapper.selectEmployeeListByDeptIds(deptIds);
    }

    @Override
    public List<EmployeeMini> selectEmployeeOfDeptIdList() {
        return employeeMapper.selectEmployeeOfDeptIdList();
    }

    @Override
    public List<EmployeeMini> selectEmployeeListByDeptId(Long deptId) {
        return employeeMapper.selectEmployeeListByDeptId(deptId);
    }

    @Override
    public List<EmployeeMiniInfo> getEmpListByName(EmployeeMiniInfo info) {
        return employeeMapper.getEmpListByName(info);
    }

    /**
     * 更新员工入职状态
     */
    @Override
    public void updateEmployeeEntryStatus(Long employeeId,Integer entryStatus){
        HrmEmployee hrmEmployee = new HrmEmployee();
        hrmEmployee.setEmployeeId(employeeId);
        hrmEmployee.setEntryStatus(entryStatus);
        this.updateById(hrmEmployee);
    }

    @Override
    public void updateEmployeePostStatus(Long employeeId, String postStatus) {
        if (employeeId != null){
            List<HrmEmployeeData> list = employeeDataService.queryListByEmployeeId(employeeId);
            if (list == null || list.isEmpty()){
                return;
            }
            List<HrmEmployeeData> dataList = list.stream().filter(item -> "post_status".equals(item.getFieldName())).collect(Collectors.toList());
            if (!dataList.isEmpty()){
                employeeDataService.lambdaUpdate().set(HrmEmployeeData::getFieldValue, postStatus)
                        .set(HrmEmployeeData::getFieldValueDesc, postStatus)
                        .eq(HrmEmployeeData::getFieldName, "post_status")
                        .eq(HrmEmployeeData::getEmployeeId, employeeId)
                        .update();
            }else {
                QueryWrapper<HrmEmployeeField> wrapper = new QueryWrapper<>();
                wrapper.eq("field_name", "post_status");
                wrapper.eq("label", 2);// 2 岗位信息
                wrapper.eq("label_group", 11);// 11 岗位信息
                HrmEmployeeField field = employeeFieldService.getOne(wrapper);
                if (field != null){
                    HrmEmployeeData data = new HrmEmployeeData();
                    data.setFieldId(field.getFieldId());
                    data.setFieldName(field.getFieldName());
                    data.setLabelGroup(field.getLabelGroup());
                    data.setName(field.getName());
                    data.setFieldValue(postStatus);
                    data.setFieldValueDesc(postStatus);
                    data.setEmployeeId(employeeId);
                    employeeDataService.save(data);
                }
            }
        }
    }

    @Override
    public List<HrmEmployeeRewardsPunishmentsVO> queryRewardsPunishmentsList(Long employeeId) {
        List<HrmEmployeeRewardsPunishments> punishmentsList = hrmEmployeeRewardsPunishmentsService.lambdaQuery()
                .eq(HrmEmployeeRewardsPunishments::getEmployeeId, employeeId)
                .eq(HrmEmployeeRewardsPunishments::getIsDel, 0)
                .list();
        List<HrmEmployeeRewardsPunishmentsVO> list = punishmentsList.stream().map(
                punishments -> {
                    HrmEmployeeRewardsPunishmentsVO vo = new HrmEmployeeRewardsPunishmentsVO();
                    BeanUtils.copyProperties(punishments, vo);
                    vo.setTypeName("1".equals(vo.getType()) ? "奖励" : "2".equals(vo.getType()) ? "惩罚":"");
                    return vo;
                }
        ).collect(Collectors.toList());
        return list;
    }

    @Override
    public OperationLog saveOrUpdateRewardsPunishments(HrmEmployeeRewardsPunishments punishments) {
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = this.getById(punishments.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        if (punishments.getId() == null) {
            punishments.setCreateUserId(UserUtil.getUserId());
            punishments.setCreateTime(LocalDateTimeUtil.now());
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.REWARDS_PUNISHMENTS, punishments.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        } else {
            punishments.setUpdateUserId(UserUtil.getUserId());
            punishments.setUpdateTime(LocalDateTimeUtil.now());
            HrmEmployeeRewardsPunishments old = hrmEmployeeRewardsPunishmentsService.getById(punishments.getId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.REWARDS_PUNISHMENTS, BeanUtil.beanToMap(old), BeanUtil.beanToMap(punishments), punishments.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        hrmEmployeeRewardsPunishmentsService.saveOrUpdate(punishments);
        return operationLog;
    }

    @Override
    public OperationLog deleteRewardsPunishments(Long id) {
        HrmEmployeeRewardsPunishments punishments = hrmEmployeeRewardsPunishmentsService.getById(id);
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = this.getById(punishments.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.REWARDS_PUNISHMENTS, punishments.getEmployeeId());

        operationLog.setOperationInfo(content.getDetail());
        hrmEmployeeRewardsPunishmentsService.removeById(id);
        return operationLog;
    }

    @Override
    public void exportEmployeeUser(HttpServletResponse response) throws IOException {
        //文件名及编码方式，System.currentTimeMillis()为当前系统的时间戳
        String filename = URLEncoder.encode(String.valueOf(System.currentTimeMillis()),"utf-8");
        //设置响应头信息：将响应内容类型设置为 Excel 文件，并指定文件名和编码方式
        response.setHeader("Content-Disposition","attachment;filename=" + filename + ".xlsx");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");


        List<EmployeeUserExportBO> empList = employeeMapper.queryExportEmployeeUser();
        // 获取部门信息
        List<HrmDept> deptList = hrmDeptService.lambdaQuery().list();
        Map<Long, HrmDept> deptMap = new HashMap<>();
        if (deptList != null && !deptList.isEmpty()){
            deptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity(), (v1, v2) -> v2));
        }
        if (empList != null && !empList.isEmpty()) {
            for (EmployeeUserExportBO emp : empList) {
                emp.setPassword("admin123");
                List<String> deptPath = getDeptPath(new ArrayList<>(), deptMap, emp.getDeptId());
                emp.setDeptPath(String.join("/", deptPath));
            }

            try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet("员工数据").head(EmployeeUserExportBO.class).build();
                // 填充数据
                excelWriter.write(empList, writeSheet);
            }
        }
    }

    private List<String> getDeptPath(List<String> deptNameList, Map<Long, HrmDept> deptMap, Long deptId) {
        if (deptMap.containsKey(deptId)) {
            getDeptPath(deptNameList, deptMap, deptMap.get(deptId).getParentId());
            deptNameList.add(deptMap.get(deptId).getName());
        }
        return deptNameList;
    }


    @Override
    public List<HrmEmployee> queryWorkbenchTotal() {
        return employeeMapper.queryWorkbenchTotal();
    }

    @Override
    public Boolean deptExistByEmployeeId(Long deptId, Long employeeId) {
        return employeeMapper.deptExistByEmployeeId(deptId, employeeId) > 0;
    }

    @Override
    public List<String> queerManageEmployeeIdList(Long deptId) {
        return employeeMapper.queerManageEmployeeIdList(deptId);
    }

    @Override
    public int pushEmployeeData(List<Long> employeeIds) {
        log.info("开始员工同步数据");
        //员工集合
        List<UserDetailInfoVO> empDetails = employeeMapper.selectPushEmployeeData(employeeIds);
        Map<String, UserDetailInfoVO> empDetailMap = new HashMap<>();
        if (!empDetails.isEmpty()) {
            empDetailMap = empDetails.stream().collect(Collectors.toMap(UserDetailInfoVO::getLoginname, v -> v));
        }
        log.info("人资人员empDetailMap数据：{}",JSON.toJSON(empDetailMap));

        //同步数据
        List<UserDetailInfoVO> addList = new ArrayList<>();
        List<UserDetailInfoVO> updateList = new ArrayList<>();
        List<String> deleteList = new ArrayList<>();
        //市政人员数据
        List<EmployeeResultVo> empResultVos = new ArrayList<>();
        for (Long empId : employeeIds) {
            HashMap<String, String> paramMap = new HashMap<>();
            paramMap.put("currentPage","1");
            paramMap.put("pageSize","1");
            paramMap.put("loginName",String.valueOf(empId));

            String resultStr = HttpUtils.createGetHttp(empGetUrl, paramMap);
            if (StrUtil.isNotEmpty(resultStr)) {
                JSONObject jsonObject = JSONObject.parseObject(resultStr);
                String text = jsonObject.getString("result");
                if (StrUtil.isNotEmpty(text)) {
                    JSONObject listObj = JSONArray.parseObject(text);
                    if (StrUtil.isNotEmpty(listObj.getString("list"))) {
                        JSONArray jsonarray = JSONArray.parseArray(listObj.getString("list"));
                        for (int n = 0; n < jsonarray.size(); n++) {
                            JSONObject json = jsonarray.getJSONObject(n);
                            EmployeeResultVo empResultVo = JSON.parseObject(String.valueOf(json), EmployeeResultVo.class);
                            empResultVos.add(empResultVo);
                        }
                    }
                }
            }
        }
        Map<String, EmployeeResultVo> empResultMap = new HashMap<>();
        if (!empResultVos.isEmpty()) {
            empResultMap = empResultVos.stream().collect(Collectors.toMap(EmployeeResultVo::getLoginname, v -> v));
        }
        log.info("市政人员empResultMap数据：{}",JSON.toJSON(empResultMap));

        HashSet<String> loginNameSet = new HashSet<>();
        loginNameSet.addAll(empResultMap.keySet());
        loginNameSet.addAll(empDetailMap.keySet());
        //数据对比
        for (String loginName : loginNameSet) {
            if (empDetailMap.containsKey(loginName) && !empResultMap.containsKey(loginName)) {
                addList.add(empDetailMap.get(loginName));
            } else if (!empDetailMap.containsKey(loginName) && empResultMap.containsKey(loginName)) {
                deleteList.add(loginName);
            } else {
                updateList.add(empDetailMap.get(loginName));
            }
        }
        log.info("对比完成");

        //同步日志详情
        List<HrmDataPushDetail> details = new ArrayList<>();
        //删除
        for (String loginName : deleteList) {
            Map<String, String> map = new HashMap();
            map.put("loginName", loginName);
            String result = HttpUtils.createPostHttp(empDeleteUrl, map);
            if (StrUtil.isNotEmpty(result)) {
                details.add(JSONObject.parseObject(result, HrmDataPushDetail.class));
            }
        }
        log.info("删除推送:{}",JSON.toJSONString(deleteList));
        //新增
        for (UserDetailInfoVO emp : addList) {
            Map<String, String> map = new HashMap();
            map.put("userDetailInfo", JSON.toJSONString(emp));
            String result = HttpUtils.createPostHttp(empAddUrl, map);
            if (StrUtil.isNotEmpty(result)) {
                details.add(JSONObject.parseObject(result, HrmDataPushDetail.class));
            }
        }
        log.info("新增推送:{}",JSON.toJSONString(addList));
        //修改
        for (UserDetailInfoVO emp : updateList) {
            Map<String, String> map = new HashMap();
            map.put("userDetailInfo", JSON.toJSONString(emp));
            String result = HttpUtils.createPostHttp(empUpdateUrl, map);
            if (StrUtil.isNotEmpty(result)) {
                details.add(JSONObject.parseObject(result, HrmDataPushDetail.class));
            }
        }
        log.info("修改推送:{}",JSON.toJSONString(updateList));
        //推送记录
        HrmDataPushLog l = new HrmDataPushLog();
        l.setType(PushDataTypeEnum.EMPLOYEE.getType());
        l.setRemark("人员数据单独推送");
        boolean save = dataPushLogService.save(l);
        log.info("推送记录保存完成");
        //保存推送详情
        if (save && !details.isEmpty()) {
            for (HrmDataPushDetail detail : details) {
                detail.setPushId(l.getId());
                detail.setCreateUserId(UserUtil.getUserId());
            }
            pushDataDetailMapper.batchInsert(details);
        }
        log.info("推送详情保存完成");
        return save ? 1 : 0;
    }

    @Override
    public void initEmployeeEsData(List<Long> employeeIds) {
//        if (employeeIds == null || employeeIds.isEmpty()) {
//            return;
//        }
//        employeeIds = Arrays.asList(822000152L,822002281L);
        ArrayList<JSONObject> resul = new ArrayList<>();
        //员工信息
        List<EmployeeElasticSearchVo>  empList =  employeeMapper.queryEmployeeElasticSearchData(employeeIds);
        log.info("员工信息查询完毕");
        //自定义字段
        List<HrmEmployeeData> list = employeeDataService.queryEmployeeDataList(employeeIds);
        Map<Long, List<HrmEmployeeData>> dataGroup = list.stream().collect(Collectors.groupingBy(HrmEmployeeData::getEmployeeId));
        log.info("员工自定义字段信息查询完毕");
        //员工部门
        List<HrmDept> deptList = hrmDeptService.lambdaQuery().list();
        Map<Long, HrmDept> deptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity()));
        log.info("员工部门信息查询完毕");
        //兼职信息
        List<ConcurrentPostVO> concurrentPostList = hrmEmployeeConcurrentPostMapper.queryEmployeeConcurrentPostList(employeeIds);
        Map<Long, List<ConcurrentPostVO>> concurrentPostGroup = new HashMap<>();
        if (concurrentPostList != null && !concurrentPostList.isEmpty()) {
            concurrentPostList.forEach(concurrentPost -> {
                //计算司龄,修改描述
                if (concurrentPost.getCompanyAgeStartTime() != null) {
                    long days = concurrentPost.getCompanyAgeStartTime().until(LocalDate.now(), ChronoUnit.DAYS);
                    String companyAgeDesc = EmployeeUtil.computeCompanyAge((int) days);
                    concurrentPost.setCompanyAge(companyAgeDesc);
                }
                if (concurrentPost.getDeptId() != null) {
                    HrmDept hrmDept = deptMap.get(concurrentPost.getDeptId());
                    if (hrmDept != null) {
                        if (hrmDept.getDeptType() == 2) {
                            concurrentPost.setDeptName(hrmDept.getName());
                            HrmDept parentDept = deptMap.get(hrmDept.getParentId());
                            if (parentDept != null) {
                                concurrentPost.setCompanyName(parentDept.getName());
                                concurrentPost.setParentDeptId(parentDept.getDeptId());
                            }
                        } else if (hrmDept.getDeptType() == 1) {
                            concurrentPost.setCompanyName(hrmDept.getName());
                            concurrentPost.setParentDeptId(hrmDept.getDeptId());
                        }
                    }
                }
            });
            concurrentPostGroup = concurrentPostList.stream().collect(Collectors.groupingBy(ConcurrentPostVO::getEmployeeId));
        }
        log.info("员工兼职信息查询完毕");
        //离职信息
        List<HrmEmployeeQuitInfo> quitList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            quitList = quitInfoService.lambdaQuery().in(HrmEmployeeQuitInfo::getEmployeeId, employeeIds).list();
        } else {
            quitList = quitInfoService.lambdaQuery().list();
        }
        Map<Long, HrmEmployeeQuitInfo> quitMap = new HashMap<>();
        if (quitList != null && !quitList.isEmpty()){
            quitList.forEach(quit -> {
                if (quit.getQuitReason() != null) {
                    quit.setQuitReasonCn(QuitReasonEnum.parseName(quit.getQuitReason()));
                }
                if (quit.getQuitType() != null) {
                    quit.setQuitTypeCn(QuitTypeEnum.parseName(quit.getQuitType()));
                }
            });
            quitMap =  quitList.stream().collect(Collectors.toMap(HrmEmployeeQuitInfo::getEmployeeId, Function.identity(), (v1, v2) -> v2));
        }
        log.info("员工离职信息查询完毕");
        //教育经历
        List<HrmEmployeeEducationExperience> educationList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            educationList = educationExperienceService.lambdaQuery().in(HrmEmployeeEducationExperience::getEmployeeId, employeeIds).list();
        }else {
            educationList = educationExperienceService.lambdaQuery().list();
        }
        Map<Long, List<HrmEmployeeEducationExperience>> educationGroup = new HashMap<>();
        if (educationList != null && !educationList.isEmpty()) {
            educationList.forEach(education -> {
                if (education.getEducation() != null) {
                    education.setEducationCn(EmployeeEducationEnum.parseName(education.getEducation()));
                }
                if (education.getDegree() != null) {
                    education.setDegreeCn(DegreeEnum.getNameByValue(education.getDegree()));
                }
                if (education.getTeachingMethods() != null) {
                    education.setTeachingMethodsCn(TeachingMethodEnum.getNameByValue(education.getTeachingMethods()));
                }
            });
            educationGroup = educationList.stream().collect(Collectors.groupingBy(HrmEmployeeEducationExperience::getEmployeeId));
        }
        log.info("员工教育经历信息查询完毕");
        //工作经历
        List<HrmEmployeeWorkExperience> workList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            workList = workExperienceService.lambdaQuery().in(HrmEmployeeWorkExperience::getEmployeeId, employeeIds).list();
        }else {
            workList = workExperienceService.lambdaQuery().list();
        }
        Map<Long, List<HrmEmployeeWorkExperience>> workGroup = new HashMap<>();
        if (workList != null && !workList.isEmpty()) {
            workGroup = workList.stream().collect(Collectors.groupingBy(HrmEmployeeWorkExperience::getEmployeeId));
        }
        log.info("员工工作经历信息查询完毕");
        //职（执）业资格
        List<HrmEmployeeCertificate> certificateList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            certificateList = certificateService.lambdaQuery().in(HrmEmployeeCertificate::getEmployeeId, employeeIds).list();
        }else {
            certificateList = certificateService.lambdaQuery().list();
        }
        Map<Long, List<HrmEmployeeCertificate>> certificateGroup = new HashMap<>();
        if (certificateList != null && !certificateList.isEmpty()) {
            certificateGroup = certificateList.stream().collect(Collectors.groupingBy(HrmEmployeeCertificate::getEmployeeId));
        }
        log.info("员工职（执）业资格信息查询完毕");
        //专业技术职务
        List<HrmEmployeeTechnical> technicalList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            technicalList = technicalService.lambdaQuery().in(HrmEmployeeTechnical::getEmployeeId, employeeIds).list();
        }else {
            technicalList = technicalService.lambdaQuery().list();
        }
        Map<Long, List<HrmEmployeeTechnical>> technicalGroup = new HashMap<>();
        if (technicalList != null && !technicalList.isEmpty()) {
            technicalGroup = technicalList.stream().collect(Collectors.groupingBy(HrmEmployeeTechnical::getEmployeeId));
        }
        log.info("员工专业技术职务信息查询完毕");
        //专业技术工人证书
        List<HrmEmployeeSpecialWorker> specialWorkerList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            specialWorkerList = specialWorkerService.lambdaQuery().in(HrmEmployeeSpecialWorker::getEmployeeId, employeeIds).list();
        }else {
            specialWorkerList = specialWorkerService.lambdaQuery().list();
        }
        Map<Long, List<HrmEmployeeSpecialWorker>> specialWorkerGroup = new HashMap<>();
        if (specialWorkerList != null && !specialWorkerList.isEmpty()) {
            specialWorkerGroup = specialWorkerList.stream().collect(Collectors.groupingBy(HrmEmployeeSpecialWorker::getEmployeeId));
        }
        log.info("员工专业技术工人证书信息查询完毕");
        //家庭成员及主要社会关系
        List<HrmEmployeeContacts> contactsList;
        if (employeeIds != null && !employeeIds.isEmpty()){
            contactsList = contactsService.lambdaQuery().in(HrmEmployeeContacts::getEmployeeId, employeeIds).list();
        }else {
            contactsList = contactsService.lambdaQuery().list();
        }
        log.info("员工家庭成员及主要社会关系信息查询完毕");
        //家庭成员自定义字段
        List<HrmEmployeeContactsData> contactsFieldValueList = contactsDataService.queryEmployeeContactsDataList(employeeIds, Lists.newArrayList(1178L, 1179L));
        Map<Long, List<HrmEmployeeContactsData>> contactsFieldValueGroup;
        if (contactsFieldValueList != null && !contactsFieldValueList.isEmpty()) {
            contactsFieldValueGroup = contactsFieldValueList.stream().collect(Collectors.groupingBy(HrmEmployeeContactsData::getContactsId));
        } else {
            contactsFieldValueGroup = new HashMap<>();
        }
        Map<Long, List<JSONObject>> contactsGroup = new HashMap<>();
        if (contactsList != null && !contactsList.isEmpty()) {
            List<JSONObject> collect = contactsList.stream().map(contacts -> {
                JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(contacts));
                if (contactsFieldValueGroup.get(contacts.getContactsId()) != null) {
                    List<HrmEmployeeContactsData> dataList = contactsFieldValueGroup.get(contacts.getContactsId());
                    dataList.forEach(data -> {
                        // 民族
                        if (data.getFieldId() == 1178L){
                            jsonObject.put("contactsNation", data.getFieldValue());
                        }
                        // 政治面貌
                        if (data.getFieldId() == 1179L) {
                            jsonObject.put("politicalOutlook", data.getFieldValue());
                        }
                    });
                }
                return jsonObject;
            }).collect(Collectors.toList());
            contactsGroup = collect.stream().collect(Collectors.groupingBy(jsonObject -> jsonObject.getLong("employeeId")));
        }
        log.info("员工家庭成员自定义字段信息查询完毕");
        log.info("员工基础信息查询完毕");
        for (int i = 0; i < empList.size(); i++) {
            EmployeeElasticSearchVo employeeElasticSearchVo = empList.get(i);
            if (employeeElasticSearchVo.getSex() != null){
                employeeElasticSearchVo.setSexCn(EmployeeSexEnum.parseName(employeeElasticSearchVo.getSex()));
            }
            if (employeeElasticSearchVo.getHighestEducation() != null){
                employeeElasticSearchVo.setHighestEducationCn(EmployeeEducationEnum.parseName(employeeElasticSearchVo.getHighestEducation()));
            }
            if (employeeElasticSearchVo.getSource() != null){
                employeeElasticSearchVo.setSourceCn(SourceEnum.getNameByValue(employeeElasticSearchVo.getSource()));
            }
            if (employeeElasticSearchVo.getProbation() != null){
                employeeElasticSearchVo.setProbationCn(ProbationEnum.getNameByValue(employeeElasticSearchVo.getProbation()));
            }
            //兼职信息
            employeeElasticSearchVo.setConcurrentPostVOList(concurrentPostGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //离职信息
            employeeElasticSearchVo.setEmployeeQuitInfo(quitMap.get(employeeElasticSearchVo.getEmployeeId()));

            //教育经历
            employeeElasticSearchVo.setEducationExperienceList(educationGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //工作经历
            employeeElasticSearchVo.setWorkExperienceList(workGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //职（执）业资格
            employeeElasticSearchVo.setCertificateList(certificateGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //专业技术职务
            employeeElasticSearchVo.setTechnicalList(technicalGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //专业技术工人证书
            employeeElasticSearchVo.setSpecialWorkerList(specialWorkerGroup.get(employeeElasticSearchVo.getEmployeeId()));

            //专业技术工人证书
            employeeElasticSearchVo.setHrmEmployeeContacts(contactsGroup.get(employeeElasticSearchVo.getEmployeeId()));

            JSONObject object = JSONObject.parseObject(JSON.toJSONString(employeeElasticSearchVo));

            //自定义字段
            if (dataGroup.containsKey(employeeElasticSearchVo.getEmployeeId())) {
                List<HrmEmployeeData> employeeDataList = dataGroup.get(employeeElasticSearchVo.getEmployeeId());
                Map<String, String> dataMap = employeeDataList.stream().collect(Collectors.toMap(HrmEmployeeData::getFieldName, entry -> Optional.ofNullable(entry.getFieldValue()).orElse("")));

                employeeDataList.forEach(data -> {
                    if ("org".equals(data.getFieldName())){
                        //任职机构
                        if (StrUtil.isNotEmpty(dataMap.get("org")) && deptMap.get(Long.valueOf(dataMap.get("org"))) != null) {
                            object.put("orgId",deptMap.get(Long.valueOf(dataMap.get("org"))).getDeptId());
                            object.put("orgName",deptMap.get(Long.valueOf(dataMap.get("org"))).getName());
                        }
                    }else if ("dept".equals(data.getFieldName())){
                        //任职部门
                        if (StrUtil.isNotEmpty(dataMap.get("dept")) && deptMap.get(Long.valueOf(dataMap.get("dept"))) != null) {
                            object.put("deptId",deptMap.get(Long.valueOf(dataMap.get("dept"))).getDeptId());
                            object.put("deptName",deptMap.get(Long.valueOf(dataMap.get("dept"))).getName());
                        }
                    }else if ("join_company_time".equals(data.getFieldName())){
                        LocalDateTime companyAgeStartTime = LocalDateTimeUtil.parse(data.getFieldValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        if (companyAgeStartTime != null){
                            object.put(StrUtil.toCamelCase(data.getFieldName()), data.getFieldValue());
                            long nowCompanyAge = LocalDateTimeUtil.between(companyAgeStartTime, LocalDateTime.now()).toDays() + 1;
                            if (LocalDateTimeUtil.toEpochMilli(companyAgeStartTime) > System.currentTimeMillis()) {
                                nowCompanyAge = 0;
                            }
                            object.put("companyAge", (int) nowCompanyAge);
                            object.put("companyAgeCn", EmployeeUtil.computeCompanyAge((int) nowCompanyAge));
                        }
                    }else {
                        if (StrUtil.isNotEmpty(data.getFieldName()) && StrUtil.isNotEmpty(data.getFieldValue()) && StrUtil.isNotEmpty(data.getFieldValue().trim())){
                            object.put(StrUtil.toCamelCase(data.getFieldName()), data.getFieldValue());
                        }
                    }
                });
            }
            resul.add(object);
        }
        log.info("向ES中添加数据");
        List<Function<BulkOperation.Builder, ObjectBuilder<BulkOperation>>> operationList = new ArrayList<>();

        for (int i = 0; i < resul.size(); i++) {
            JSONObject object = resul.get(i);
            operationList.add(EsUtil.indexOperations(object.get("employeeId"), HrmElasticSearchIndexEnum.EMPLOYEE.getIndex(), object));
        }
        EsUtil.bulk(operationList);
        log.info("向ES中添加数据完成");
    }

    @Override
    public PersonalInformationHighlightVO personalInformationHighlight(QueryEmployeePostInformation employeePostInformation) {
        QueryEmployeePageListBO employeePageListBO = new QueryEmployeePageListBO();
        employeePageListBO.setEmployeeName(employeePostInformation.getQueryContent());
        employeePageListBO.setPage(1L);
        employeePageListBO.setLimit(1L);
        employeePageListBO.setIsOtherInfo(true);
        BasePage<Map<String, Object>> mapBasePage =
                this.fullTextSearch(employeePageListBO, Lists.newArrayList(employeePostInformation.getEmployeeId()));

        List<Map<String, Object>> list = mapBasePage.getList();
        //基本信息
        List<InformationFieldVO> information = new ArrayList<>();
        //紧急联系人信息
        List<InformationFieldVO> communicationInformation = new ArrayList<>();
        //教育经历
        List<JSONObject> educationExperienceList = new ArrayList<>();
        //工作经历
        List<JSONObject> workExperienceList = new ArrayList<>();
        //职（执）业资格
        List<JSONObject> certificateList = new ArrayList<>();
        //专业技术职务
        List<JSONObject> technicalList = new ArrayList<>();
        //专技工人证书
        List<JSONObject> specialWorkerList = new ArrayList<>();
        //家庭成员及主要社会关系
        List<Map<String, Object>> hrmEmployeeContacts = new ArrayList<>();
        if (!list.isEmpty()) {
            Map<String, Object> map = list.get(0);
            List<String> keyList = Arrays.stream(employeePageListBO.getEmployeeName().split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
            //基本信息
            List<String> filedList = Lists.newArrayList("sex", "source","probation", "highestEducation");
            JSONObject employeeModel = BeanUtil.copyProperties(map, JSONObject.class);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeePostInformation.getEmployeeId());
            information = transferInformation(employeeModel, LabelGroupEnum.PERSONAL, fieldValueList);
            for (InformationFieldVO informationFieldVO : information) {
                for (String key : keyList) {
                    if (filedList.contains(informationFieldVO.getFieldName()) && informationFieldVO.getFieldValueDesc().toString().contains(key)){
                        String replace = informationFieldVO.getFieldValueDesc().toString().replaceAll(key, "<font color='red'>" + key + "</font>");
                        informationFieldVO.setFormType("esText");
                        informationFieldVO.setFieldValue(replace);
                        informationFieldVO.setFieldValueDesc(replace);
                    }else if (informationFieldVO.getFieldValue() != null && informationFieldVO.getFieldValue().toString().contains(key)){
                        String replace = informationFieldVO.getFieldValue().toString().replaceAll(key, "<font color='red'>" + key + "</font>");
                        informationFieldVO.setFormType("esText");
                        informationFieldVO.setFieldValue(replace);
                        informationFieldVO.setFieldValueDesc(replace);
                    }
                }
            }

            //通讯信息
            communicationInformation = transferInformation(employeeModel, LabelGroupEnum.COMMUNICATION, fieldValueList);
            for (InformationFieldVO communication : communicationInformation) {
                for (String key : keyList) {
                    if (communication.getFieldValue() != null && communication.getFieldValue().toString().contains(key)){
                        String replace = communication.getFieldValue().toString().replaceAll(key, "<font color='red'>" + key + "</font>");
                        communication.setFormType("esText");
                        communication.setFieldValue(replace);
                        communication.setFieldValueDesc(replace);
                    }
                }
            }

            //教育经历
            Object educationExperience = map.get("educationExperienceList");
            if (educationExperience != null) {
                educationExperienceList = JSONObject.parseArray(JSONUtil.toJsonStr(educationExperience), JSONObject.class);
                if (!educationExperienceList.isEmpty()){
                    educationExperienceList = educationExperienceList.stream().sorted(Comparator.comparing(o -> {
                        return LocalDateTimeUtil.parse(((JSONObject) o).getString("admissionTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    }, Comparator.nullsLast(LocalDateTime::compareTo)).thenComparing(jo -> {
                        String educationId = ((JSONObject) jo).getString("educationId");
                        return Long.parseLong(educationId);
                    })).collect(Collectors.toList());
                }
                for (int i = 0; i < educationExperienceList.size(); i++) {
                    JSONObject jsonObject = educationExperienceList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }

            //工作经历
            Object workExperience = map.get("workExperienceList");
            if (workExperience != null) {
                workExperienceList = JSONObject.parseArray(JSONUtil.toJsonStr(workExperience), JSONObject.class);
                if (!workExperienceList.isEmpty()){
                    workExperienceList = workExperienceList.stream().sorted(Comparator.comparing(o -> {
                        return LocalDateTimeUtil.parse(((JSONObject) o).getString("workStartTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    }, Comparator.nullsLast(LocalDateTime::compareTo)).thenComparing(jo -> {
                        String educationId = ((JSONObject) jo).getString("workExpId");
                        return Long.parseLong(educationId);
                    })).collect(Collectors.toList());
                }
                for (int i = 0; i < workExperienceList.size(); i++) {
                    JSONObject jsonObject = workExperienceList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }

            //职（执）业资格
            Object certificate = map.get("certificateList");
            if (certificate != null) {
                certificateList = JSONObject.parseArray(JSONUtil.toJsonStr(certificate), JSONObject.class);
                for (int i = 0; i < certificateList.size(); i++) {
                    JSONObject jsonObject = certificateList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }


            //专业技术职务
            Object technical = map.get("technicalList");
            if (technical != null) {
                technicalList = JSONObject.parseArray(JSONUtil.toJsonStr(technical), JSONObject.class);
                for (int i = 0; i < technicalList.size(); i++) {
                    JSONObject jsonObject = technicalList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }

            //专技工人证书
            Object specialWorker = map.get("specialWorkerList");
            if (specialWorker != null) {
                specialWorkerList = JSONObject.parseArray(JSONUtil.toJsonStr(specialWorker), JSONObject.class);
                for (int i = 0; i < specialWorkerList.size(); i++) {
                    JSONObject jsonObject = specialWorkerList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }
            //家庭成员及主要社会关系
            Object contactsObject = map.get("hrmEmployeeContacts");
//            if (contacts != null) {
//                List<JSONObject> hrmEmployeeContactsList = JSONObject.parseArray(JSONUtil.toJsonStr(contacts), JSONObject.class);
//                for (int i = 0; i < hrmEmployeeContactsList.size(); i++) {
//                    JSONObject jsonObject = hrmEmployeeContactsList.get(i);
//                    Set<String> strings = jsonObject.keySet();
//                    strings.forEach(fieldName -> {
//                        String value = jsonObject.get(fieldName).toString();
//                        if (value != null && !value.equals("null")) {
//                            for (String key : keyList) {
//                                if (value.contains(key)){
//                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
//                                    jsonObject.put(fieldName, replace);
//                                }
//                            }
//                        }
//                    });
//                    Map<String, Object> hrmEmployeeContact = new HashMap<>();
//                    hrmEmployeeContact.put("contactsId", jsonObject.get("contactsId"));
//                    hrmEmployeeContact.put("contactsName", jsonObject);
//                    hrmEmployeeContacts.add(hrmEmployeeContact);
//                }
//            }

            //联系人信息
            List<HrmEmployeeContacts> contactsList = JSONObject.parseArray(JSONUtil.toJsonStr(contactsObject), HrmEmployeeContacts.class);
            if(contactsList != null && !contactsList.isEmpty()){
                contactsList.forEach(contacts -> {
                    QueryWrapper<HrmEmployeeContactsData> eq = Wrappers.<HrmEmployeeContactsData>query().select("field_id", "field_value", "field_value_desc").eq("contacts_id", contacts.getContactsId());
                    List<HrmEmployeeContactsData> contactsDataList = contactsDataService.list(eq);
                    //联系人自定义字段值
                    List<HrmEmployeeData> contactsFieldValueList = TransferUtil.transferList(contactsDataList, HrmEmployeeData.class);
                    Map<String, Object> hrmEmployeeContact = new HashMap<>();
                    List<InformationFieldVO> contactField = transferInformation(BeanUtil.copyProperties(contacts, JSONObject.class), LabelGroupEnum.CONTACT_PERSON, contactsFieldValueList);
                    if (contactField != null && !contactField.isEmpty()) {
                        contactField.forEach(field -> {
                            if (field.getFieldValue() != null) {
                                for (String key : keyList) {
                                    if (field.getFieldValue().toString().contains(key)){
                                        String replace = field.getFieldValue().toString().replaceAll(key, "<font color='red'>" + key + "</font>");
                                        field.setFieldValue(replace);
                                    }
                                }
                            }
                        });
                    }
                    hrmEmployeeContact.put("contactsId", contacts.getContactsId());
                    hrmEmployeeContact.put("information", contactField);
                    hrmEmployeeContacts.add(hrmEmployeeContact);
                });
            }
        }
        return new PersonalInformationHighlightVO(information, communicationInformation, educationExperienceList, workExperienceList, certificateList,technicalList, specialWorkerList, hrmEmployeeContacts);
    }


    @Override
    public List<Map<String, Object>> queryEmployeeFixedField(List<Long> employeeIds) {
        List<Map<String, Object>> employeeList = employeeMapper.queryEmployeeFixedField(employeeIds);
        employeeList.forEach(map -> {
            Object object = map.get("companyAgeStartTime");
            if (object != null && !StrUtil.isEmpty(object.toString())){
                LocalDateTime companyAgeStartTime = LocalDateTimeUtil.parse(object.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"));
                if (companyAgeStartTime != null){
                    long nowCompanyAge = LocalDateTimeUtil.between(companyAgeStartTime, LocalDateTime.now()).toDays() + 1;
                    if (LocalDateTimeUtil.toEpochMilli(companyAgeStartTime) > System.currentTimeMillis()) {
                        nowCompanyAge = 0;
                    }
                    map.put("companyAge", String.valueOf(nowCompanyAge));
                }
            }
        });
        return employeeList;
    }

    /**
     * 在事务提交后更新ES数据
     */
    public void updateESAfterCommit(Long employeeId) {
        if (employeeId != null) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    initEmployeeEsData(Lists.newArrayList(employeeId));
                }
            });
        }
    }
}
